2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file sql_connection.h
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the implementation file of SQL connection
22 #ifndef DPL_SQL_CONNECTION_H
23 #define DPL_SQL_CONNECTION_H
25 #include <dpl/noncopyable.h>
26 #include <dpl/exception.h>
27 #include <dpl/availability.h>
29 #include <boost/optional.hpp>
30 #include <dpl/string.h>
31 #include <dpl/log/log.h>
34 #include <dpl/assert.h>
41 * SQL connection class
47 * SQL Exception classes
52 DECLARE_EXCEPTION_TYPE(DPL::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)
59 typedef int ColumnIndex;
60 typedef int ArgumentIndex;
63 * SQL processed data command
69 SqlConnection *m_masterConnection;
72 void CheckBindResult(int result);
73 void CheckColumnIndex(SqlConnection::ColumnIndex column);
75 DataCommand(SqlConnection *connection, const char *buffer);
77 friend class SqlConnection;
80 virtual ~DataCommand();
83 * Bind null to the prepared statement argument
85 * @param position Index of argument to bind value to
87 void BindNull(ArgumentIndex position);
90 * Bind int to the prepared statement argument
92 * @param position Index of argument to bind value to
93 * @param value Value to bind
95 void BindInteger(ArgumentIndex position, int value);
98 * Bind int8_t to the prepared statement argument
100 * @param position Index of argument to bind value to
101 * @param value Value to bind
103 void BindInt8(ArgumentIndex position, int8_t value);
106 * Bind int16 to the prepared statement argument
108 * @param position Index of argument to bind value to
109 * @param value Value to bind
111 void BindInt16(ArgumentIndex position, int16_t value);
114 * Bind int32 to the prepared statement argument
116 * @param position Index of argument to bind value to
117 * @param value Value to bind
119 void BindInt32(ArgumentIndex position, int32_t value);
122 * Bind int64 to the prepared statement argument
124 * @param position Index of argument to bind value to
125 * @param value Value to bind
127 void BindInt64(ArgumentIndex position, int64_t value);
130 * Bind float to the prepared statement argument
132 * @param position Index of argument to bind value to
133 * @param value Value to bind
135 void BindFloat(ArgumentIndex position, float value);
138 * Bind double to the prepared statement argument
140 * @param position Index of argument to bind value to
141 * @param value Value to bind
143 void BindDouble(ArgumentIndex position, double value);
146 * Bind string to the prepared statement argument
148 * @param position Index of argument to bind value to
149 * @param value Value to bind
151 void BindString(ArgumentIndex position, const char *value);
154 * Bind string to the prepared statement argument
156 * @param position Index of argument to bind value to
157 * @param value Value to bind
159 void BindString(ArgumentIndex position, const String& value);
162 * Bind optional int to the prepared statement argument.
163 * If optional is not set null will be bound
165 * @param position Index of argument to bind value to
166 * @param value Value to bind
168 void BindInteger(ArgumentIndex position, const boost::optional<int> &value);
171 * Bind optional int8 to the prepared statement argument.
172 * If optional is not set null will be bound
174 * @param position Index of argument to bind value to
175 * @param value Value to bind
177 void BindInt8(ArgumentIndex position, const boost::optional<int8_t> &value);
180 * Bind optional int16 to the prepared statement argument.
181 * If optional is not set null will be bound
183 * @param position Index of argument to bind value to
184 * @param value Value to bind
186 void BindInt16(ArgumentIndex position, const boost::optional<int16_t> &value);
189 * Bind optional int32 to the prepared statement argument.
190 * If optional is not set null will be bound
192 * @param position Index of argument to bind value to
193 * @param value Value to bind
195 void BindInt32(ArgumentIndex position, const boost::optional<int32_t> &value);
198 * Bind optional int64 to the prepared statement argument.
199 * If optional is not set null will be bound
201 * @param position Index of argument to bind value to
202 * @param value Value to bind
204 void BindInt64(ArgumentIndex position, const boost::optional<int64_t> &value);
207 * Bind optional float to the prepared statement argument.
208 * If optional is not set null will be bound
210 * @param position Index of argument to bind value to
211 * @param value Value to bind
213 void BindFloat(ArgumentIndex position, const boost::optional<float> &value);
216 * Bind optional double to the prepared statement argument.
217 * If optional is not set null will be bound
219 * @param position Index of argument to bind value to
220 * @param value Value to bind
222 void BindDouble(ArgumentIndex position, const boost::optional<double> &value);
225 * Bind optional string to the prepared statement argument.
226 * If optional is not set null will be bound
228 * @param position Index of argument to bind value to
229 * @param value Value to bind
231 void BindString(ArgumentIndex position, const boost::optional<String> &value);
234 * Execute the prepared statement and/or move
235 * to the next row of the result
237 * @return True when there was a row returned
242 * Reset prepared statement's arguments
243 * All parameters will become null
248 * Checks whether column value is null
250 * @throw Exception::InvalidColumn
252 bool IsColumnNull(ColumnIndex column);
255 * Get integer value from column in current row.
257 * @throw Exception::InvalidColumn
259 int GetColumnInteger(ColumnIndex column);
262 * Get int8 value from column in current row.
264 * @throw Exception::InvalidColumn
266 int8_t GetColumnInt8(ColumnIndex column);
269 * Get int16 value from column in current row.
271 * @throw Exception::InvalidColumn
273 int16_t GetColumnInt16(ColumnIndex column);
275 * Get int32 value from column in current row.
277 * @throw Exception::InvalidColumn
279 int32_t GetColumnInt32(ColumnIndex column);
282 * Get int64 value from column in current row.
284 * @throw Exception::InvalidColumn
286 int64_t GetColumnInt64(ColumnIndex column);
289 * Get float value from column in current row.
291 * @throw Exception::InvalidColumn
293 float GetColumnFloat(ColumnIndex column);
296 * Get double value from column in current row.
298 * @throw Exception::InvalidColumn
300 double GetColumnDouble(ColumnIndex column);
303 * Get string value from column in current row.
305 * @throw Exception::InvalidColumn
307 std::string GetColumnString(ColumnIndex column);
310 * Get optional integer value from column in current row.
312 * @throw Exception::InvalidColumn
314 boost::optional<int> GetColumnOptionalInteger(ColumnIndex column);
317 * Get optional int8 value from column in current row.
319 * @throw Exception::InvalidColumn
321 boost::optional<int8_t> GetColumnOptionalInt8(ColumnIndex column);
324 * Get optional int16value from column in current row.
326 * @throw Exception::InvalidColumn
328 boost::optional<int16_t> GetColumnOptionalInt16(ColumnIndex column);
331 * Get optional int32 value from column in current row.
333 * @throw Exception::InvalidColumn
335 boost::optional<int32_t> GetColumnOptionalInt32(ColumnIndex column);
338 * Get optional int64 value from column in current row.
340 * @throw Exception::InvalidColumn
342 boost::optional<int64_t> GetColumnOptionalInt64(ColumnIndex column);
345 * Get optional float value from column in current row.
347 * @throw Exception::InvalidColumn
349 boost::optional<float> GetColumnOptionalFloat(ColumnIndex column);
352 * Get optional double value from column in current row.
354 * @throw Exception::InvalidColumn
356 boost::optional<double> GetColumnOptionalDouble(ColumnIndex column);
359 * Get optional string value from column in current row.
361 * @throw Exception::InvalidColumn
363 boost::optional<String> GetColumnOptionalString(ColumnIndex column);
366 // Move on copy semantics
367 typedef std::auto_ptr<DataCommand> DataCommandAutoPtr;
381 RO = SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READONLY,
383 * *TODO: please remove CREATE option from RW flag when all places
384 * that need that switched do CRW
386 RW = SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE |
388 CRW = RW | SQLITE_OPEN_CREATE
393 typedef sqlite3_int64 RowID;
396 * Synchronization object used to synchronize SQL connection
397 * to the same database across different threads and processes
399 class SynchronizationObject
402 virtual ~SynchronizationObject() {}
405 * Synchronizes SQL connection for multiple clients.
407 virtual void Synchronize() = 0;
410 * Notify all waiting clients that the connection is no longer locked.
412 virtual void NotifyAll() = 0;
416 sqlite3 *m_connection;
421 // Stored data procedures
422 int m_dataCommandsCount;
424 // Synchronization object
425 std::unique_ptr<SynchronizationObject> m_synchronizationObject;
427 virtual void Connect(const std::string &address,
428 Flag::Type = Flag::None, Flag::Option = Flag::RO);
429 virtual void Disconnect();
431 void TurnOnForeignKeys();
433 static SynchronizationObject *AllocDefaultSynchronizationObject();
437 * Open SQL connection
439 * Synchronization is archieved by using provided asynchronization object.
440 * If synchronizationObject is set to NULL, so synchronization is performed.
441 * Ownership of the synchronization object is transfered to sql connection
444 * @param address Database file name
445 * @param flags Open flags
446 * @param synchronizationObject A synchronization object to use.
448 explicit SqlConnection(const std::string &address = std::string(),
449 Flag::Type flags = Flag::None,
450 Flag::Option options = Flag::RO,
451 SynchronizationObject *synchronizationObject =
452 AllocDefaultSynchronizationObject());
457 virtual ~SqlConnection();
460 * Execute SQL command without result
465 void ExecCommand(const char *format, ...) DPL_DEPRECATED_WITH_MESSAGE(
466 "To prevent sql injection do not use this \
467 method for direct sql execution");
470 * Execute BEGIN; command to start new transaction
473 void BeginTransaction();
476 * Execute ROLLBACK; command to discard changes made
479 void RollbackTransaction();
482 * Execute COMMIT; command to commit changes in database
485 void CommitTransaction();
488 * Prepare stored procedure
490 * @param format SQL statement
491 * @return Data command representing stored procedure
493 DataCommandAutoPtr PrepareDataCommand(const char *format, ...);
496 * Check whether given table exists
498 * @param tableName Name of the table to check
499 * @return True if given table name exists
501 bool CheckTableExist(const char *tableName);
504 * Get last insert operation new row id
508 RowID GetLastInsertRowID() const;
513 #endif // DPL_SQL_CONNECTION_H