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