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