tizen beta release
[framework/web/wrt-commons.git] / modules / db / include / dpl / db / sql_connection.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        sql_connection.h
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of SQL connection
21  */
22 #ifndef DPL_SQL_CONNECTION_H
23 #define DPL_SQL_CONNECTION_H
24
25 #include <dpl/noncopyable.h>
26 #include <dpl/exception.h>
27 #include <dpl/optional.h>
28 #include <dpl/scoped_ptr.h>
29 #include <dpl/string.h>
30 #include <dpl/log/log.h>
31 #include <sqlite3.h>
32 #include <string>
33 #include <dpl/assert.h>
34 #include <memory>
35 #include <stdint.h>
36
37 namespace DPL
38 {
39 namespace DB
40 {
41
42 /**
43  * SQL connection class
44  */
45 class SqlConnection
46 {
47 public:
48     /**
49      * SQL Exception classes
50      */
51     class Exception
52     {
53     public:
54         DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
55         DECLARE_EXCEPTION_TYPE(Base, SyntaxError)
56         DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken)
57         DECLARE_EXCEPTION_TYPE(Base, InternalError)
58         DECLARE_EXCEPTION_TYPE(Base, InvalidColumn)
59     };
60
61     typedef int ColumnIndex;
62     typedef int ArgumentIndex;
63
64     /*
65      * SQL processed data command
66      */
67     class DataCommand
68         : private Noncopyable
69     {
70     private:
71         SqlConnection *m_masterConnection;
72         sqlite3_stmt *m_stmt;
73
74         void CheckBindResult(int result);
75         void CheckColumnIndex(SqlConnection::ColumnIndex column);
76
77         DataCommand(SqlConnection *connection, const char *buffer);
78
79         friend class SqlConnection;
80
81     public:
82         virtual ~DataCommand();
83
84         /**
85          * Bind null to the prepared statement argument
86          *
87          * @param position Index of argument to bind value to
88          */
89         void BindNull(ArgumentIndex position);
90
91         /**
92          * Bind int to the prepared statement argument
93          *
94          * @param position Index of argument to bind value to
95          * @param value Value to bind
96          */
97         void BindInteger(ArgumentIndex position, int value);
98
99         /**
100          * Bind int8_t to the prepared statement argument
101          *
102          * @param position Index of argument to bind value to
103          * @param value Value to bind
104          */
105         void BindInt8(ArgumentIndex position, int8_t value);
106
107         /**
108          * Bind int16 to the prepared statement argument
109          *
110          * @param position Index of argument to bind value to
111          * @param value Value to bind
112          */
113         void BindInt16(ArgumentIndex position, int16_t value);
114
115         /**
116          * Bind int32 to the prepared statement argument
117          *
118          * @param position Index of argument to bind value to
119          * @param value Value to bind
120          */
121         void BindInt32(ArgumentIndex position, int32_t value);
122
123         /**
124          * Bind int64 to the prepared statement argument
125          *
126          * @param position Index of argument to bind value to
127          * @param value Value to bind
128          */
129         void BindInt64(ArgumentIndex position, int64_t value);
130
131         /**
132          * Bind float to the prepared statement argument
133          *
134          * @param position Index of argument to bind value to
135          * @param value Value to bind
136          */
137         void BindFloat(ArgumentIndex position, float value);
138
139         /**
140          * Bind double to the prepared statement argument
141          *
142          * @param position Index of argument to bind value to
143          * @param value Value to bind
144          */
145         void BindDouble(ArgumentIndex position, double value);
146
147         /**
148          * Bind string to the prepared statement argument
149          *
150          * @param position Index of argument to bind value to
151          * @param value Value to bind
152          */
153         void BindString(ArgumentIndex position, const char *value);
154
155         /**
156          * Bind string to the prepared statement argument
157          *
158          * @param position Index of argument to bind value to
159          * @param value Value to bind
160          */
161         void BindString(ArgumentIndex position, const String& value);
162
163         /**
164          * Bind optional int to the prepared statement argument.
165          * If optional is not set null will be bound
166          *
167          * @param position Index of argument to bind value to
168          * @param value Value to bind
169          */
170         void BindInteger(ArgumentIndex position, const Optional<int> &value);
171
172         /**
173          * Bind optional int8 to the prepared statement argument.
174          * If optional is not set null will be bound
175          *
176          * @param position Index of argument to bind value to
177          * @param value Value to bind
178          */
179         void BindInt8(ArgumentIndex position, const Optional<int8_t> &value);
180
181         /**
182          * Bind optional int16 to the prepared statement argument.
183          * If optional is not set null will be bound
184          *
185          * @param position Index of argument to bind value to
186          * @param value Value to bind
187          */
188         void BindInt16(ArgumentIndex position, const Optional<int16_t> &value);
189
190         /**
191          * Bind optional int32 to the prepared statement argument.
192          * If optional is not set null will be bound
193          *
194          * @param position Index of argument to bind value to
195          * @param value Value to bind
196          */
197         void BindInt32(ArgumentIndex position, const Optional<int32_t> &value);
198
199         /**
200          * Bind optional int64 to the prepared statement argument.
201          * If optional is not set null will be bound
202          *
203          * @param position Index of argument to bind value to
204          * @param value Value to bind
205          */
206         void BindInt64(ArgumentIndex position, const Optional<int64_t> &value);
207
208         /**
209          * Bind optional float to the prepared statement argument.
210          * If optional is not set null will be bound
211          *
212          * @param position Index of argument to bind value to
213          * @param value Value to bind
214          */
215         void BindFloat(ArgumentIndex position, const Optional<float> &value);
216
217         /**
218          * Bind optional double to the prepared statement argument.
219          * If optional is not set null will be bound
220          *
221          * @param position Index of argument to bind value to
222          * @param value Value to bind
223          */
224         void BindDouble(ArgumentIndex position, const Optional<double> &value);
225
226         /**
227          * Bind optional string to the prepared statement argument.
228          * If optional is not set null will be bound
229          *
230          * @param position Index of argument to bind value to
231          * @param value Value to bind
232          */
233         void BindString(ArgumentIndex position, const Optional<String> &value);
234
235         /**
236          * Execute the prepared statement and/or move
237          * to the next row of the result
238          *
239          * @return True when there was a row returned
240          */
241         bool Step();
242
243         /**
244          * Reset prepared statement's arguments
245          * All parameters will become null
246          */
247         void Reset();
248
249         /**
250          * Checks whether column value is null
251          *
252          * @throw Exception::InvalidColumn
253          */
254         bool IsColumnNull(ColumnIndex column);
255
256         /**
257          * Get integer value from column in current row.
258          *
259          * @throw Exception::InvalidColumn
260          */
261         int GetColumnInteger(ColumnIndex column);
262
263         /**
264          * Get int8 value from column in current row.
265          *
266          * @throw Exception::InvalidColumn
267          */
268         int8_t GetColumnInt8(ColumnIndex column);
269
270         /**
271          * Get int16 value from column in current row.
272          *
273          * @throw Exception::InvalidColumn
274          */
275         int16_t GetColumnInt16(ColumnIndex column);
276         /**
277          * Get int32 value from column in current row.
278          *
279          * @throw Exception::InvalidColumn
280          */
281         int32_t GetColumnInt32(ColumnIndex column);
282
283         /**
284          * Get int64 value from column in current row.
285          *
286          * @throw Exception::InvalidColumn
287          */
288         int64_t GetColumnInt64(ColumnIndex column);
289
290         /**
291          * Get float value from column in current row.
292          *
293          * @throw Exception::InvalidColumn
294          */
295         float GetColumnFloat(ColumnIndex column);
296
297         /**
298          * Get double value from column in current row.
299          *
300          * @throw Exception::InvalidColumn
301          */
302         double GetColumnDouble(ColumnIndex column);
303
304         /**
305          * Get string value from column in current row.
306          *
307          * @throw Exception::InvalidColumn
308          */
309         std::string GetColumnString(ColumnIndex column);
310
311         /**
312          * Get optional integer value from column in current row.
313          *
314          * @throw Exception::InvalidColumn
315          */
316         Optional<int> GetColumnOptionalInteger(ColumnIndex column);
317
318         /**
319          * Get optional int8 value from column in current row.
320          *
321          * @throw Exception::InvalidColumn
322          */
323         Optional<int8_t> GetColumnOptionalInt8(ColumnIndex column);
324
325         /**
326          * Get optional int16value from column in current row.
327          *
328          * @throw Exception::InvalidColumn
329          */
330         Optional<int16_t> GetColumnOptionalInt16(ColumnIndex column);
331
332         /**
333          * Get optional int32 value from column in current row.
334          *
335          * @throw Exception::InvalidColumn
336          */
337         Optional<int32_t> GetColumnOptionalInt32(ColumnIndex column);
338
339         /**
340          * Get optional int64 value from column in current row.
341          *
342          * @throw Exception::InvalidColumn
343          */
344         Optional<int64_t> GetColumnOptionalInt64(ColumnIndex column);
345
346         /**
347          * Get optional float value from column in current row.
348          *
349          * @throw Exception::InvalidColumn
350          */
351         Optional<float> GetColumnOptionalFloat(ColumnIndex column);
352
353         /**
354          * Get optional double value from column in current row.
355          *
356          * @throw Exception::InvalidColumn
357          */
358         Optional<double> GetColumnOptionalDouble(ColumnIndex column);
359
360         /**
361          * Get optional string value from column in current row.
362          *
363          * @throw Exception::InvalidColumn
364          */
365         Optional<String> GetColumnOptionalString(ColumnIndex column);
366     };
367
368     // Move on copy semantics
369     typedef std::auto_ptr<DataCommand> DataCommandAutoPtr;
370
371     // Open flags
372     class Flag
373     {
374     public:
375         enum Type
376         {
377             None      = 1<<0,
378             UseLucene = 1<<1
379         };
380     };
381
382     // RowID
383     typedef sqlite3_int64 RowID;
384
385     /**
386      * Synchronization object used to synchronize SQL connection
387      * to the same database across different threads and processes
388      */
389     class SynchronizationObject
390     {
391     public:
392         virtual ~SynchronizationObject() {}
393
394         /**
395          * Synchronizes SQL connection for multiple clients.
396          */
397         virtual void Synchronize() = 0;
398
399         /**
400          * Notify all waiting clients that the connection is no longer locked.
401          */
402         virtual void NotifyAll() = 0;
403     };
404
405 protected:
406     sqlite3 *m_connection;
407
408     // Options
409     bool m_usingLucene;
410
411     // Stored data procedures
412     int m_dataCommandsCount;
413
414     // Synchronization object
415     ScopedPtr<SynchronizationObject> m_synchronizationObject;
416
417     virtual void Connect(const std::string &address, Flag::Type = Flag::None);
418     virtual void Disconnect();
419
420     void TurnOnForeignKeys();
421
422     static SynchronizationObject *AllocDefaultSynchronizationObject();
423
424 public:
425     /**
426      * Open SQL connection
427      *
428      * Synchronization is archieved by using provided asynchronization object.
429      * If synchronizationObject is set to NULL, so synchronization is performed.
430      * Ownership of the synchronization object is transfered to sql connection
431      * object.
432      *
433      * @param address Database file name
434      * @param flags Open flags
435      * @param synchronizationObject A synchronization object to use.
436      */
437     explicit SqlConnection(const std::string &address = std::string(),
438                            Flag::Type flags = Flag::None,
439                            SynchronizationObject *synchronizationObject =
440                                AllocDefaultSynchronizationObject());
441
442     /**
443      * Destructor
444      */
445     virtual ~SqlConnection();
446
447     /**
448      * Execute SQL command without result
449      *
450      * @param format
451      * @param ...
452      */
453     void ExecCommand(const char *format, ...);
454
455     /**
456      * Prepare stored procedure
457      *
458      * @param format SQL statement
459      * @return Data command representing stored procedure
460      */
461     DataCommandAutoPtr PrepareDataCommand(const char *format, ...);
462
463     /**
464      * Check whether given table exists
465      *
466      * @param tableName Name of the table to check
467      * @return True if given table name exists
468      */
469     bool CheckTableExist(const char *tableName);
470
471     /**
472      * Get last insert operation new row id
473      *
474      * @return Row ID
475      */
476     RowID GetLastInsertRowID() const;
477 };
478
479 } // namespace DB
480 } // namespace DPL
481
482 #endif // DPL_SQL_CONNECTION_H