mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-29 17:29:20 +00:00
feat(EventsDb): provide interface
This commit is contained in:
parent
0399162c4c
commit
6df37d30f9
8 changed files with 198 additions and 55 deletions
|
|
@ -34,8 +34,8 @@ bool AbstractDb::connect (Backend backend, const string ¶meters) {
|
|||
L_D(AbstractDb);
|
||||
|
||||
d->dbSession = DbSessionProvider::getInstance()->getSession(
|
||||
(backend == Mysql ? "mysql://" : "sqlite3://") + parameters
|
||||
);
|
||||
(backend == Mysql ? "mysql://" : "sqlite3://") + parameters
|
||||
);
|
||||
|
||||
if (d->dbSession)
|
||||
init();
|
||||
|
|
|
|||
|
|
@ -16,17 +16,21 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
#include <soci/soci.h>
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
#include "abstract/abstract-db-p.h"
|
||||
#include "event/call-event.h"
|
||||
#include "event/event.h"
|
||||
#include "event/message-event.h"
|
||||
|
||||
#include "events-db.h"
|
||||
|
||||
// TODO: Remove me.
|
||||
#ifdef SOCI_ENABLED
|
||||
#undef SOCI_ENABLED
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class EventsDbPrivate : public AbstractDbPrivate {};
|
||||
|
|
@ -37,34 +41,34 @@ EventsDb::EventsDb () : AbstractDb(*new EventsDbPrivate) {}
|
|||
|
||||
void EventsDb::init () {
|
||||
#ifdef SOCI_ENABLED
|
||||
|
||||
L_D(EventsDb);
|
||||
soci::session *session = d->dbSession.getBackendSession<soci::session>();
|
||||
|
||||
d->session <<
|
||||
*session <<
|
||||
"CREATE TABLE IF NOT EXISTS sip_address ("
|
||||
" id" + primaryKeyAutoIncrementStr() + ","
|
||||
" value VARCHAR(255) NOT NULL"
|
||||
")";
|
||||
|
||||
d->session <<
|
||||
*session <<
|
||||
"CREATE TABLE IF NOT EXISTS event ("
|
||||
" id" + primaryKeyAutoIncrementStr() + ","
|
||||
" timestamp TIMESTAMP NOT NULL"
|
||||
")";
|
||||
|
||||
d->session <<
|
||||
*session <<
|
||||
"CREATE TABLE IF NOT EXISTS message_status ("
|
||||
" id" + primaryKeyAutoIncrementStr() + ","
|
||||
" status VARCHAR(255) NOT NULL"
|
||||
")";
|
||||
|
||||
d->session <<
|
||||
*session <<
|
||||
"CREATE TABLE IF NOT EXISTS message_direction ("
|
||||
" id" + primaryKeyAutoIncrementStr() + ","
|
||||
" direction VARCHAR(255) NOT NULL"
|
||||
")";
|
||||
|
||||
d->session <<
|
||||
*session <<
|
||||
"CREATE TABLE IF NOT EXISTS dialog ("
|
||||
" local_sip_address_id BIGINT UNSIGNED NOT NULL," // Sip address used to communicate.
|
||||
" remote_sip_address_id BIGINT UNSIGNED NOT NULL," // Server (for conference) or user sip address.
|
||||
|
|
@ -78,7 +82,7 @@ void EventsDb::init () {
|
|||
" ON DELETE CASCADE"
|
||||
")";
|
||||
|
||||
d->session <<
|
||||
*session <<
|
||||
"CREATE TABLE IF NOT EXISTS message_event ("
|
||||
" id" + primaryKeyAutoIncrementStr() + ","
|
||||
" dialog_id BIGINT UNSIGNED NOT NULL,"
|
||||
|
|
@ -99,7 +103,74 @@ void EventsDb::init () {
|
|||
" ON DELETE CASCADE"
|
||||
")";
|
||||
|
||||
#endif // ifndef SOCI_ENABLED
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool EventsDb::addEvent (const Event &event) {
|
||||
// TODO.
|
||||
switch (event.getType()) {
|
||||
case Event::None:
|
||||
return false;
|
||||
case Event::MessageEvent:
|
||||
case Event::CallStartEvent:
|
||||
case Event::CallEndEvent:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EventsDb::deleteEvent (const Event &event) {
|
||||
// TODO.
|
||||
(void)event;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EventsDb::cleanEvents (FilterMask mask) {
|
||||
// TODO.
|
||||
(void)mask;
|
||||
}
|
||||
|
||||
int EventsDb::getEventsCount (FilterMask mask) {
|
||||
// TODO.
|
||||
(void)mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EventsDb::getMessagesCount (const string &remoteAddress) {
|
||||
// TODO.
|
||||
(void)remoteAddress;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EventsDb::getUnreadMessagesCount (const string &remoteAddress) {
|
||||
// TODO.
|
||||
(void)remoteAddress;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list<Event> EventsDb::getHistory (const string &remoteAddress, int nLast, FilterMask mask) {
|
||||
// TODO.
|
||||
(void)remoteAddress;
|
||||
(void)nLast;
|
||||
(void)mask;
|
||||
return list<Event>();
|
||||
}
|
||||
|
||||
list<Event> EventsDb::getHistory (const string &remoteAddress, int begin, int end, FilterMask mask) {
|
||||
// TODO.
|
||||
(void)remoteAddress;
|
||||
(void)begin;
|
||||
(void)end;
|
||||
(void)mask;
|
||||
return list<Event>();
|
||||
}
|
||||
|
||||
void EventsDb::cleanHistory (const string &remoteAddress) {
|
||||
// TODO.
|
||||
(void)remoteAddress;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#ifndef _EVENTS_DB_H_
|
||||
#define _EVENTS_DB_H_
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "abstract/abstract-db.h"
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -30,9 +32,29 @@ class EventsDbPrivate;
|
|||
|
||||
class LINPHONE_PUBLIC EventsDb : public AbstractDb {
|
||||
public:
|
||||
enum Filter {
|
||||
NoFilter = 0x0,
|
||||
MessageFilter = 0x1,
|
||||
CallFilter = 0x2,
|
||||
ConferenceFilter = 0x4
|
||||
};
|
||||
|
||||
typedef int FilterMask;
|
||||
|
||||
EventsDb ();
|
||||
|
||||
bool writeEvent (const Event &event);
|
||||
// Generic.
|
||||
bool addEvent (const Event &event);
|
||||
bool deleteEvent (const Event &event);
|
||||
void cleanEvents (FilterMask mask = NoFilter);
|
||||
int getEventsCount (FilterMask mask = NoFilter);
|
||||
|
||||
// Messages, calls and conferences.
|
||||
int getMessagesCount (const std::string &remoteAddress);
|
||||
int getUnreadMessagesCount (const std::string &remoteAddress);
|
||||
std::list<Event> getHistory (const std::string &remoteAddress, int nLast, FilterMask mask = NoFilter);
|
||||
std::list<Event> getHistory (const std::string &remoteAddress, int begin, int end, FilterMask mask = NoFilter);
|
||||
void cleanHistory (const std::string &remoteAddress);
|
||||
|
||||
protected:
|
||||
void init () override;
|
||||
|
|
|
|||
|
|
@ -19,32 +19,25 @@
|
|||
#ifndef _DB_SESSION_P_H_
|
||||
#define _DB_SESSION_P_H_
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
#include <memory>
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
#include <memory>
|
||||
|
||||
#include "db-session.h"
|
||||
#include "object/clonable-object-p.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
namespace soci {
|
||||
class session;
|
||||
}
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class DbSessionPrivate : public ClonableObjectPrivate {
|
||||
friend class DbSessionProvider;
|
||||
|
||||
private:
|
||||
bool isValid = false;
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
std::shared_ptr<soci::session> session;
|
||||
#endif // ifndef SOCI_ENABLED
|
||||
DbSession::Type type = DbSession::None;
|
||||
std::shared_ptr<void> backendSession;
|
||||
|
||||
L_DECLARE_PUBLIC(DbSession);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
#include <unordered_map>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
#include <soci/soci.h>
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
|
|
@ -37,45 +37,45 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
class DbSessionProviderPrivate : public ObjectPrivate {
|
||||
public:
|
||||
#ifdef SOCI_ENABLED
|
||||
typedef pair<weak_ptr<soci::session>, DbSessionPrivate *> InternalSession;
|
||||
unordered_map<string, InternalSession> sessions;
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
typedef pair<weak_ptr<void>, DbSessionPrivate *> InternalSession;
|
||||
unordered_map<string, InternalSession> sessions;
|
||||
int cleanCounter = 0;
|
||||
};
|
||||
|
||||
DbSessionProvider::DbSessionProvider () : Singleton(*new DbSessionProviderPrivate) {}
|
||||
|
||||
DbSession DbSessionProvider::getSession (const string &uri) {
|
||||
DbSession session;
|
||||
L_D(DbSessionProvider);
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
L_D(DbSessionProvider);
|
||||
DbSession session(DbSession::Soci);
|
||||
try {
|
||||
shared_ptr<soci::session> sociSession = d->sessions[uri].first.lock();
|
||||
if (!sociSession) { // Create new session.
|
||||
sociSession = make_shared<soci::session>(uri);
|
||||
shared_ptr<void> backendSession = d->sessions[uri].first.lock();
|
||||
++d->cleanCounter;
|
||||
if (!backendSession) { // Create new session.
|
||||
backendSession = make_shared<soci::session>(uri);
|
||||
DbSessionPrivate *p = session.getPrivate();
|
||||
p->session = sociSession;
|
||||
p->backendSession = backendSession;
|
||||
p->isValid = true;
|
||||
d->sessions[uri] = make_pair(sociSession, p);
|
||||
d->sessions[uri] = make_pair(backendSession, p);
|
||||
} else // Share session.
|
||||
session.setRef(*d->sessions[uri].second);
|
||||
} catch (const exception &) {}
|
||||
#else
|
||||
DbSession session(DbSession::None);
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
// Remove invalid weak ptrs.
|
||||
if (++d->cleanCounter >= CLEAN_COUNTER_MAX) {
|
||||
d->cleanCounter = 0;
|
||||
// Remove invalid weak ptrs.
|
||||
if (d->cleanCounter >= CLEAN_COUNTER_MAX) {
|
||||
d->cleanCounter = 0;
|
||||
|
||||
for (auto it = d->sessions.begin(), itEnd = d->sessions.end(); it != itEnd;) {
|
||||
if (it->second.first.expired())
|
||||
it = d->sessions.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
for (auto it = d->sessions.begin(), itEnd = d->sessions.end(); it != itEnd;) {
|
||||
if (it->second.first.expired())
|
||||
it = d->sessions.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
#endif // ifndef SOCI_ENABLED
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ using namespace std;
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
DbSession::DbSession (Type type) : ClonableObject(*new DbSessionPrivate) {
|
||||
L_D(DbSession);
|
||||
d->type = type;
|
||||
}
|
||||
|
||||
L_USE_DEFAULT_SHARE_IMPL(DbSession, ClonableObject);
|
||||
|
||||
DbSession::operator bool () const {
|
||||
|
|
@ -33,4 +38,14 @@ DbSession::operator bool () const {
|
|||
return d->isValid;
|
||||
}
|
||||
|
||||
DbSession::Type DbSession::getBackendType () const {
|
||||
L_D(const DbSession);
|
||||
return d->type;
|
||||
}
|
||||
|
||||
void *DbSession::getBackendSession () const {
|
||||
L_D(const DbSession);
|
||||
return d->backendSession.get();
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@
|
|||
|
||||
// =============================================================================
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
namespace soci {
|
||||
class session;
|
||||
}
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class DbSessionPrivate;
|
||||
|
|
@ -33,17 +39,54 @@ class DbSession : public ClonableObject {
|
|||
friend class DbSessionProvider;
|
||||
|
||||
public:
|
||||
DbSession ();
|
||||
enum Type {
|
||||
None,
|
||||
Soci
|
||||
};
|
||||
|
||||
DbSession (Type type = None);
|
||||
DbSession (const DbSession &src);
|
||||
|
||||
DbSession &operator= (const DbSession &src);
|
||||
|
||||
operator bool () const;
|
||||
|
||||
Type getBackendType () const;
|
||||
|
||||
template<typename T>
|
||||
T *getBackendSession () const;
|
||||
|
||||
private:
|
||||
void *getBackendSession () const;
|
||||
|
||||
L_DECLARE_PRIVATE(DbSession);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
struct TypeOfDbSession {
|
||||
static const DbSession::Type type = DbSession::None;
|
||||
};
|
||||
|
||||
#ifdef SOCI_ENABLED
|
||||
|
||||
template<>
|
||||
struct TypeOfDbSession<::soci::session> {
|
||||
static const DbSession::Type type = DbSession::Soci;
|
||||
};
|
||||
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
template<typename T>
|
||||
T *DbSession::getBackendSession () const {
|
||||
typedef TypeOfDbSession<T> Type;
|
||||
static_assert(Type::type != DbSession::None, "Unable to get backend session, invalid type.");
|
||||
if (getBackendType() != Type::type)
|
||||
return nullptr;
|
||||
return static_cast<T *>(getBackendSession());
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _DB_SESSION_H_
|
||||
|
|
|
|||
|
|
@ -110,8 +110,7 @@ inline const Object *getPublicHelper (const T *object, const ObjectPrivate *) {
|
|||
#define L_Q(CLASS) CLASS * const q = getPublic();
|
||||
|
||||
#define L_USE_DEFAULT_SHARE_IMPL(CLASS, PARENT_CLASS) \
|
||||
CLASS::CLASS () : PARENT_CLASS(*new CLASS ## Private) {} \
|
||||
CLASS::CLASS (const CLASS &src) : ClonableObject(*src.getPrivate()) {} \
|
||||
CLASS::CLASS (const CLASS &src) : PARENT_CLASS(*src.getPrivate()) {} \
|
||||
CLASS &CLASS::operator= (const CLASS &src) { \
|
||||
if (this != &src) \
|
||||
setRef(*src.getPrivate()); \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue