/* * db-session-provider.cpp * Copyright (C) 2010-2017 Belledonne Communications SARL * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef SOCI_ENABLED #include #endif // ifdef SOCI_ENABLED #include "db-session-p.h" #include "logger/logger.h" #include "object/object-p.h" #include "db-session-provider.h" #define CLEAN_COUNTER_MAX 1000 // ============================================================================= using namespace std; LINPHONE_BEGIN_NAMESPACE class DbSessionProviderPrivate : public ObjectPrivate { public: typedef pair, DbSessionPrivate *> InternalSession; unordered_map sessions; int cleanCounter = 0; }; DbSessionProvider::DbSessionProvider () : Singleton(*new DbSessionProviderPrivate) {} DbSession DbSessionProvider::getSession (const string &uri) { L_D(); #ifdef SOCI_ENABLED DbSession session(DbSession::Soci); try { shared_ptr backendSession = d->sessions[uri].first.lock(); ++d->cleanCounter; if (!backendSession) { // Create new session. backendSession = make_shared(uri); DbSessionPrivate *p = session.getPrivate(); p->backendSession = backendSession; p->isValid = true; d->sessions[uri] = make_pair(backendSession, p); } else // Share session. session.setRef(*d->sessions[uri].second); } catch (const exception &e) { lWarning() << "Unable to get db session: " << e.what(); } #else DbSession session(DbSession::None); lWarning() << "Unable to get db session: soci not enabled."; #endif // ifdef SOCI_ENABLED // 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; } } return session; } LINPHONE_END_NAMESPACE