From 6df37d30f90a4a768acb3c45f4172f8eb0a61e9f Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 23 Aug 2017 15:53:50 +0200 Subject: [PATCH] feat(EventsDb): provide interface --- src/db/abstract/abstract-db.cpp | 4 +- src/db/events-db.cpp | 97 +++++++++++++++++++++---- src/db/events-db.h | 24 +++++- src/db/provider/db-session-p.h | 17 ++--- src/db/provider/db-session-provider.cpp | 48 ++++++------ src/db/provider/db-session.cpp | 15 ++++ src/db/provider/db-session.h | 45 +++++++++++- src/utils/general.h | 3 +- 8 files changed, 198 insertions(+), 55 deletions(-) diff --git a/src/db/abstract/abstract-db.cpp b/src/db/abstract/abstract-db.cpp index 63e2fcef4..39101ff00 100644 --- a/src/db/abstract/abstract-db.cpp +++ b/src/db/abstract/abstract-db.cpp @@ -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(); diff --git a/src/db/events-db.cpp b/src/db/events-db.cpp index 8a949c0e8..82431fa0a 100644 --- a/src/db/events-db.cpp +++ b/src/db/events-db.cpp @@ -16,17 +16,21 @@ * along with this program. If not, see . */ +#ifdef SOCI_ENABLED + #include +#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(); - 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 EventsDb::getHistory (const string &remoteAddress, int nLast, FilterMask mask) { + // TODO. + (void)remoteAddress; + (void)nLast; + (void)mask; + return list(); +} + +list EventsDb::getHistory (const string &remoteAddress, int begin, int end, FilterMask mask) { + // TODO. + (void)remoteAddress; + (void)begin; + (void)end; + (void)mask; + return list(); +} + +void EventsDb::cleanHistory (const string &remoteAddress) { + // TODO. + (void)remoteAddress; } LINPHONE_END_NAMESPACE diff --git a/src/db/events-db.h b/src/db/events-db.h index 3cd201a25..1c77af3a9 100644 --- a/src/db/events-db.h +++ b/src/db/events-db.h @@ -19,6 +19,8 @@ #ifndef _EVENTS_DB_H_ #define _EVENTS_DB_H_ +#include + #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 getHistory (const std::string &remoteAddress, int nLast, FilterMask mask = NoFilter); + std::list getHistory (const std::string &remoteAddress, int begin, int end, FilterMask mask = NoFilter); + void cleanHistory (const std::string &remoteAddress); protected: void init () override; diff --git a/src/db/provider/db-session-p.h b/src/db/provider/db-session-p.h index 597ceaa44..de9e9b5da 100644 --- a/src/db/provider/db-session-p.h +++ b/src/db/provider/db-session-p.h @@ -19,32 +19,25 @@ #ifndef _DB_SESSION_P_H_ #define _DB_SESSION_P_H_ -#ifdef SOCI_ENABLED - #include -#endif // ifdef SOCI_ENABLED +#include #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 session; - #endif // ifndef SOCI_ENABLED + DbSession::Type type = DbSession::None; + std::shared_ptr backendSession; L_DECLARE_PUBLIC(DbSession); }; diff --git a/src/db/provider/db-session-provider.cpp b/src/db/provider/db-session-provider.cpp index 04c8bb98e..35dc9c82c 100644 --- a/src/db/provider/db-session-provider.cpp +++ b/src/db/provider/db-session-provider.cpp @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -#ifdef SOCI_ENABLED - #include +#include +#ifdef SOCI_ENABLED #include #endif // ifdef SOCI_ENABLED @@ -37,45 +37,45 @@ LINPHONE_BEGIN_NAMESPACE class DbSessionProviderPrivate : public ObjectPrivate { public: - #ifdef SOCI_ENABLED - typedef pair, DbSessionPrivate *> InternalSession; - unordered_map sessions; - #endif // ifdef SOCI_ENABLED - + typedef pair, DbSessionPrivate *> InternalSession; + unordered_map 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 sociSession = d->sessions[uri].first.lock(); - if (!sociSession) { // Create new session. - sociSession = make_shared(uri); + shared_ptr backendSession = d->sessions[uri].first.lock(); + ++d->cleanCounter; + if (!backendSession) { // Create new session. + backendSession = make_shared(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; } diff --git a/src/db/provider/db-session.cpp b/src/db/provider/db-session.cpp index ac1f85d52..f074804b3 100644 --- a/src/db/provider/db-session.cpp +++ b/src/db/provider/db-session.cpp @@ -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 diff --git a/src/db/provider/db-session.h b/src/db/provider/db-session.h index 35eb6fe59..ac8a0582e 100644 --- a/src/db/provider/db-session.h +++ b/src/db/provider/db-session.h @@ -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 + T *getBackendSession () const; + private: + void *getBackendSession () const; + L_DECLARE_PRIVATE(DbSession); }; +// ----------------------------------------------------------------------------- + +template +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 +T *DbSession::getBackendSession () const { + typedef TypeOfDbSession Type; + static_assert(Type::type != DbSession::None, "Unable to get backend session, invalid type."); + if (getBackendType() != Type::type) + return nullptr; + return static_cast(getBackendSession()); +} + LINPHONE_END_NAMESPACE #endif // ifndef _DB_SESSION_H_ diff --git a/src/utils/general.h b/src/utils/general.h index 7f46799b8..243c7a7ca 100644 --- a/src/utils/general.h +++ b/src/utils/general.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()); \