forked from mirrors/linphone-iphone
167 lines
4 KiB
C++
167 lines
4 KiB
C++
/*
|
|
* abstract-db.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 <soci/soci.h>
|
|
#endif // ifdef SOCI_ENABLED
|
|
|
|
#ifdef __APPLE__
|
|
#include <TargetConditionals.h>
|
|
#endif // ifdef __APPLE__
|
|
|
|
#include "abstract-db-p.h"
|
|
#include "db/session/db-session-provider.h"
|
|
#include "logger/logger.h"
|
|
|
|
// =============================================================================
|
|
|
|
using namespace std;
|
|
|
|
LINPHONE_BEGIN_NAMESPACE
|
|
|
|
AbstractDb::AbstractDb (AbstractDbPrivate &p) : Object(p) {}
|
|
|
|
// Force static sqlite3 linking for IOS and Android.
|
|
#if TARGET_OS_IPHONE || defined(__ANDROID__)
|
|
extern "C" void register_factory_sqlite3();
|
|
#endif // TARGET_OS_IPHONE || defined(__ANDROID__)
|
|
|
|
bool AbstractDb::connect (Backend backend, const string ¶meters) {
|
|
L_D();
|
|
|
|
#if TARGET_OS_IPHONE || defined(__ANDROID__)
|
|
if (backend == Sqlite3)
|
|
register_factory_sqlite3();
|
|
#endif // defined(TARGET_OS_IPHONE) || defined(__ANDROID__)
|
|
|
|
d->backend = backend;
|
|
d->dbSession = DbSessionProvider::getInstance()->getSession(
|
|
(backend == Mysql ? "mysql://" : "sqlite3://") + parameters
|
|
);
|
|
|
|
if (d->dbSession) {
|
|
try {
|
|
enableForeignKeys(false);
|
|
init();
|
|
enableForeignKeys(true);
|
|
} catch (const exception &e) {
|
|
lWarning() << "Unable to init database: " << e.what();
|
|
|
|
// Reset session.
|
|
d->dbSession = DbSession();
|
|
}
|
|
}
|
|
|
|
return d->dbSession;
|
|
}
|
|
|
|
bool AbstractDb::isConnected () const {
|
|
L_D();
|
|
return d->dbSession;
|
|
}
|
|
|
|
AbstractDb::Backend AbstractDb::getBackend () const {
|
|
L_D();
|
|
return d->backend;
|
|
}
|
|
|
|
bool AbstractDb::import (Backend, const string &) {
|
|
return false;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void AbstractDb::init () {
|
|
// Nothing.
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
string AbstractDb::primaryKeyStr (const string &type) const {
|
|
L_D();
|
|
|
|
switch (d->backend) {
|
|
case Mysql:
|
|
return type + " PRIMARY KEY AUTO_INCREMENT";
|
|
case Sqlite3:
|
|
// See: ROWIDs and the INTEGER PRIMARY KEY
|
|
// https://www.sqlite.org/lang_createtable.html
|
|
return " INTEGER PRIMARY KEY ASC";
|
|
}
|
|
|
|
L_ASSERT(false);
|
|
return "";
|
|
}
|
|
|
|
string AbstractDb::primaryKeyRefStr (const string &type) const {
|
|
L_D();
|
|
|
|
switch (d->backend) {
|
|
case Mysql:
|
|
return " " + type;
|
|
case Sqlite3:
|
|
return " INTEGER";
|
|
}
|
|
|
|
L_ASSERT(false);
|
|
return "";
|
|
}
|
|
|
|
long long AbstractDb::getLastInsertId () const {
|
|
long long id = 0;
|
|
|
|
#ifdef SOCI_ENABLED
|
|
L_D();
|
|
|
|
string sql;
|
|
switch (d->backend) {
|
|
case Mysql:
|
|
sql = "SELECT LAST_INSERT_ID()";
|
|
break;
|
|
case Sqlite3:
|
|
sql = "SELECT last_insert_rowid()";
|
|
break;
|
|
default:
|
|
lWarning() << "Unsupported backend.";
|
|
return -1;
|
|
}
|
|
|
|
soci::session *session = d->dbSession.getBackendSession<soci::session>();
|
|
*session << sql, soci::into(id);
|
|
#endif // ifdef SOCI_ENABLED
|
|
|
|
return id;
|
|
}
|
|
|
|
void AbstractDb::enableForeignKeys (bool status) {
|
|
#ifdef SOCI_ENABLED
|
|
L_D();
|
|
soci::session *session = d->dbSession.getBackendSession<soci::session>();
|
|
switch (d->backend) {
|
|
case Mysql:
|
|
*session << string("SET FOREIGN_KEY_CHECKS = ") + (status ? "1" : "0");
|
|
break;
|
|
case Sqlite3:
|
|
*session << string("PRAGMA foreign_keys = ") + (status ? "ON" : "OFF");
|
|
break;
|
|
}
|
|
#endif // ifdef SOCI_ENABLED
|
|
}
|
|
|
|
LINPHONE_END_NAMESPACE
|