Imported Upstream version 0.7
[platform/upstream/syncevolution.git] / src / SQLiteSyncSource.h
1 /*
2  * Copyright (C) 2007 Patrick Ohly
3  * Copyright (C) 2007 Funambol
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #ifndef INCL_SQLITESYNCSOURCE
21 #define INCL_SQLITESYNCSOURCE
22
23 #include "EvolutionSyncSource.h"
24
25 #ifdef ENABLE_SQLITE
26
27 #include <sqlite3.h>
28 #include "EvolutionSmartPtr.h"
29
30 namespace vocl {
31     class VObject;
32 }
33 void inline unref(sqlite3 *db) { sqlite3_close(db); }
34 void inline unref(sqlite3_stmt *stmt) { sqlite3_finalize(stmt); }
35
36 /**
37  * This class implements access to SQLite database files:
38  * - opening the database file
39  * - error reporting
40  * - creating a database file in debugging mode
41  */
42 class SQLiteSyncSource : public EvolutionSyncSource
43 {
44   public:
45     /**
46      * Creates a new Evolution sync source.
47      *
48      * @param    name        the named needed by SyncSource
49      * @param    sc          obligatory config for this source, must remain valid throughout the lifetime of the source
50      * @param    changeId    is used to track changes in the Evolution backend
51      * @param    id          identifies the backend; not specifying it makes this instance
52      *                       unusable for anything but listing backend databases
53      */
54     SQLiteSyncSource( const string name, SyncSourceConfig *sc, const string &changeId, const string &id ) :
55     EvolutionSyncSource( name, sc, changeId, id),
56         m_db(NULL)
57         {}
58     virtual ~SQLiteSyncSource() {}
59
60     /* implementation of EvolutionSyncSource interface */
61     virtual sources getSyncBackends() { return sources(); /* we cannot list available databases */ }
62     virtual void open();
63     virtual void close();
64
65
66  protected:
67     /** throw error for a specific sqlite3 operation on m_db */
68     void throwError(const string &operation);
69
70     /**
71      * wrapper around sqlite3_prepare() which operates on the current
72      * database and throws an error if the call fails
73      *
74      * @param sqlfmt         printf-style format string for query, followed by parameters for sprintf
75      */
76     sqlite3_stmt *prepareSQL(const char *sqlfmt, ...);
77
78     /**
79      * wrapper around sqlite3_prepare() which operates on the current
80      * database and throws an error if the call fails
81      *
82      * @param sql       preformatted SQL statement(s)
83      * @param nextsql   pointer to next statement in sql
84      */
85     sqlite3_stmt *prepareSQLWrapper(const char *sql, const char **nextsql = NULL);
86
87
88     /** checks the result of an sqlite3 call, throws an error if faulty, otherwise returns the result */
89     int checkSQL(int res, const char *operation = "SQLite call") {
90         if (res != SQLITE_OK && res != SQLITE_ROW && res != SQLITE_DONE) {
91             throwError(operation);
92         }
93         return res;
94     }
95
96     /** type used for row keys */
97     typedef long long key_t;
98     string toString(key_t key) { char buffer[32]; sprintf(buffer, "%lld", key); return buffer; }
99 #define SQLITE3_COLUMN_KEY sqlite3_column_int64
100
101     /** return row ID for a certain row */
102     key_t findKey(const char *database, const char *keyname, const char *key);
103
104     /** return a specific column for a row identified by a certain key column as text, returns default text if not found */
105     string findColumn(const char *database, const char *keyname, const char *key, const char *column, const char *def);
106
107     /** a wrapper for sqlite3_column_test() which will check for NULL and returns default text instead */
108     string getTextColumn(sqlite3_stmt *stmt, int col, const char *def = "");
109
110     typedef unsigned long syncml_time_t;
111     /** transform column to same time base as used by SyncML libary (typically time()) */
112     syncml_time_t getTimeColumn(sqlite3_stmt *stmt, int col);
113
114     /** copies all columns which directly map to a property into the vobj */
115     void rowToVObject(sqlite3_stmt *stmt, vocl::VObject &vobj);
116
117     /** database schema to use when creating new databases, may be NULL */
118     virtual const char *getDefaultSchema() = 0;
119
120     /** information about the database mapping */
121     struct Mapping {
122         const char *colname;        /**< column name in SQL table */
123         const char *tablename;      /**< name of the SQL table which has this column */
124         const char *propname;       /**< optional: vcard/vcalendar property which corresponds to this */
125         int colindex;               /**< determined dynamically in open(): index of the column, -1 if not present */
126     };
127
128     /**
129      * array with database mapping, terminated by NULL colname:
130      * variable fields are stored in a copy maintained by the SQLiteSyncSource class
131      */
132     virtual const Mapping *getConstMapping() = 0;
133
134     /** filled in by SQLiteSyncSource::open() */
135     arrayptr<Mapping> m_mapping;
136
137     /** after opening: current databse */
138     eptr<sqlite3> m_db;
139 };
140
141 #endif // ENABLE_SQLITE
142 #endif // INCL_SQLITESYNCSOURCE