syncevolution/src/backends/sqlite/SQLiteUtil.h
Patrick Ohly de8461f802 code restructing: Exception, throwError()
Raising exceptions via throwError() looses the original source code
location information. Fixing that by explicitly passing that
information as additional parameter, created with the preprocessor
macro SE_HERE.

Several files included the complex SyncContext.h only because needed
throwError(). A better place for the revised implementation is the
Exception class which used to be in util.h, now Exception.h.

Simplifying the include statements exposed indirect include
dependencies and removed "using namespace std" from the compilation of
some source files which happened to rely on it. We want to get rid of
that name space polution, so fix the code instead of adding it back.
2014-05-02 16:43:52 +02:00

145 lines
5.1 KiB
C++

/*
* Copyright (C) 2007-2009 Patrick Ohly <patrick.ohly@gmx.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef INCL_SQLITESYNCSOURCE
#define INCL_SQLITESYNCSOURCE
#ifdef ENABLE_SQLITE
#include <sqlite3.h>
#include <syncevo/SmartPtr.h>
#include <syncevo/Exception.h>
#include <string>
#include <stdio.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
using namespace std;
class SQLiteUnref {
public:
static void unref(sqlite3 *db) { sqlite3_close(db); }
static void unref(sqlite3_stmt *stmt) { sqlite3_finalize(stmt); }
};
typedef eptr<sqlite3_stmt, sqlite3_stmt, SQLiteUnref> sqliteptr;
/**
* This class implements access to SQLite database files:
* - opening the database file
* - error reporting
* - creating a database file
* - converting to and from a VObject via a simple property<->column name mapping
*/
class SQLiteUtil
{
public:
/** information about the database mapping */
struct Mapping {
const char *colname; /**< column name in SQL table */
const char *tablename; /**< name of the SQL table which has this column */
const char *fieldname; /**< synthesis internal field name, no corresponding synthesis field if empty*/
int colindex; /**< determined dynamically in open(): index of the column, -1 if not present */
};
const Mapping &getMapping(int i) { return m_mapping[i]; }
/**
* @param name a name for the data source, used for error messages
* @param fileid a descriptor which identifies the file to be opened:
* currently valid syntax is file:// followed by path
* @param mapping array with database mapping, terminated by NULL colname
* @param schema database schema to use when creating new databases, may be NULL
*/
void open(const string &name,
const string &fileid,
const Mapping *mapping,
const char *schema);
void close();
/**
* throw error for a specific sqlite3 operation on m_db
* @param operation a description of the operation which failed
*/
void throwError(const SourceLocation &where, const string &operation);
/**
* wrapper around sqlite3_prepare() which operates on the current
* database and throws an error if the call fails
*
* @param sqlfmt printf-style format string for query, followed by parameters for sprintf
*/
sqlite3_stmt *prepareSQL(const char *sqlfmt, ...);
/**
* wrapper around sqlite3_prepare() which operates on the current
* database and throws an error if the call fails
*
* @param sql preformatted SQL statement(s)
* @param nextsql pointer to next statement in sql
*/
sqlite3_stmt *prepareSQLWrapper(const char *sql, const char **nextsql = NULL);
/** checks the result of an sqlite3 call, throws an error if faulty, otherwise returns the result */
int checkSQL(int res, const char *operation = "SQLite call") {
if (res != SQLITE_OK && res != SQLITE_ROW && res != SQLITE_DONE) {
throwError(SE_HERE, operation);
}
return res;
}
/** type used for row keys */
typedef long long key_t;
string toString(key_t key) { char buffer[32]; sprintf(buffer, "%lld", key); return buffer; }
#define SQLITE3_COLUMN_KEY sqlite3_column_int64
/** return row ID for a certain row */
key_t findKey(const char *database, const char *keyname, const char *key);
/** return a specific column for a row identified by a certain key column as text, returns default text if not found */
string findColumn(const char *database, const char *keyname, const char *key, const char *column, const char *def);
/** a wrapper for sqlite3_column_test() which will check for NULL and returns default text instead */
string getTextColumn(sqlite3_stmt *stmt, int col, const char *def = "");
typedef unsigned long syncml_time_t;
/** transform column to same time base as used by SyncML libary (typically time()) */
syncml_time_t getTimeColumn(sqlite3_stmt *stmt, int col);
/** convert time to string */
static string time2str(syncml_time_t t);
private:
/* copy of open() parameters */
arrayptr<Mapping> m_mapping;
string m_name;
string m_fileid;
/** current database */
eptr<sqlite3, sqlite3, SQLiteUnref> m_db;
};
SE_END_CXX
#endif // ENABLE_SQLITE
#endif // INCL_SQLITESYNCSOURCE