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 thread_database_support.h
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk)
20 * @brief This file contains the declaration of thread database support
23 #ifndef DPL_THREAD_DATABASE_SUPPORT_H
24 #define DPL_THREAD_DATABASE_SUPPORT_H
27 #include <dpl/log/wrt_log.h>
28 #include <dpl/db/sql_connection.h>
29 #include <dpl/db/orm_interface.h>
30 #include <dpl/thread.h>
31 #include <dpl/assert.h>
37 * Thread database support
39 * Associate database connection with thread lifecycle
43 class ThreadDatabaseSupport :
44 public DPL::DB::ORM::IOrmInterface
47 typedef DPL::DB::SqlConnection *SqlConnectionPtr;
48 typedef DPL::ThreadLocalVariable<SqlConnectionPtr> TLVSqlConnectionPtr;
49 typedef DPL::ThreadLocalVariable<size_t> TLVSizeT;
50 typedef DPL::ThreadLocalVariable<bool> TLVBool;
52 TLVSqlConnectionPtr m_connection;
54 TLVSizeT m_refCounter;
55 TLVSizeT m_transactionDepth;
56 TLVSizeT m_attachCount;
57 TLVBool m_transactionCancel;
58 std::string m_address;
59 DPL::DB::SqlConnection::Flag::Type m_flags;
61 TLVSqlConnectionPtr &Connection()
71 TLVSizeT &RefCounter()
76 TLVSizeT &TransactionDepth()
78 return m_transactionDepth;
81 TLVSizeT &AttachCount()
86 TLVBool &TransactionCancel()
88 return m_transactionCancel;
91 void CheckedConnectionDelete()
93 Assert(!Connection().IsNull());
94 Assert(*Linger() == true);
96 if (*RefCounter() > 0 || *AttachCount() > 0) {
100 // Destroy connection
101 WrtLogD("Destroying thread database connection: %s", m_address.c_str());
103 delete *Connection();
106 Connection().GuardValue(false);
107 Linger().GuardValue(false);
108 RefCounter().GuardValue(false);
109 TransactionCancel().GuardValue(false);
110 TransactionDepth().GuardValue(false);
111 AttachCount().GuardValue(false);
113 Connection().Reset();
115 RefCounter().Reset();
116 TransactionCancel().Reset();
117 TransactionDepth().Reset();
118 AttachCount().Reset();
121 void TransactionUnref()
123 WrtLogD("Unref transaction");
125 if (--(*TransactionDepth()) == 0) {
126 WrtLogD("Transaction is finalized");
128 if (*TransactionCancel()) {
129 WrtLogD("Transaction will be rolled back");
130 (*Connection())->RollbackTransaction();
132 WrtLogD("Transaction will be commited");
133 (*Connection())->CommitTransaction();
139 ThreadDatabaseSupport(const std::string &address,
140 DPL::DB::SqlConnection::Flag::Type flags) :
145 virtual ~ThreadDatabaseSupport()
149 DPL::DB::SqlConnection::Flag::Option options =
150 DPL::DB::SqlConnection::Flag::RO)
154 if (!Connection().IsNull()) {
160 // Initialize SQL connection described in traits
161 WrtLogD("Attaching thread database connection: %s", m_address.c_str());
163 Connection() = new DPL::DB::SqlConnection(
164 m_address.c_str(), m_flags, options);
170 //Init Transaction related variables
171 TransactionDepth() = 0;
172 TransactionCancel() = false;
175 Connection().GuardValue(true);
176 Linger().GuardValue(true);
177 RefCounter().GuardValue(true);
178 TransactionDepth().GuardValue(true);
179 AttachCount().GuardValue(true);
180 TransactionCancel().GuardValue(true);
183 void DetachFromThread()
185 // Calling thread must support thread database connections
186 Assert(!Connection().IsNull());
191 if (*AttachCount() > 0) {
195 // It must not be in linger state yet
196 Assert(*Linger() == false);
198 WrtLogD("Detaching thread database connection: %s", m_address.c_str());
200 // Enter linger state
204 CheckedConnectionDelete();
209 return !AttachCount().IsNull() && *AttachCount() > 0;
212 DPL::DB::SqlConnection::DataCommand *AllocDataCommand(
213 const std::string &statement)
215 // Calling thread must support thread database connections
216 Assert(!Connection().IsNull());
218 // Calling thread must not be in linger state
219 Assert(*Linger() == false);
224 // Create new unmanaged data command
225 return (*Connection())->PrepareDataCommand(statement.c_str()).release();
228 void FreeDataCommand(DPL::DB::SqlConnection::DataCommand *command)
230 // Calling thread must support thread database connections
231 Assert(!Connection().IsNull());
233 // Delete data command
236 // Unreference SQL connection
239 // If it is linger state, connection may be destroyed
240 if (*Linger() == true) {
241 CheckedConnectionDelete();
245 void TransactionBegin()
247 // Calling thread must support thread database connections
248 Assert(!Connection().IsNull());
250 WrtLogD("Begin transaction");
252 // Addref transaction
253 if (++(*TransactionDepth()) == 1) {
254 WrtLogD("Transaction is initialized");
256 TransactionCancel() = false;
257 (*Connection())->BeginTransaction();
261 void TransactionCommit()
263 // Calling thread must support thread database connections
264 Assert(!Connection().IsNull());
266 WrtLogD("Commit transaction");
272 void TransactionRollback()
274 // Calling thread must support thread database connections
275 Assert(!Connection().IsNull());
277 // Cancel and unref transaction
278 TransactionCancel() = true;
282 DPL::DB::SqlConnection::RowID GetLastInsertRowID()
284 // Calling thread must support thread database connections
285 Assert(!Connection().IsNull());
287 return (*Connection())->GetLastInsertRowID();
290 bool CheckTableExist(const char *name)
292 // Calling thread must support thread database connections
293 Assert(!Connection().IsNull());
295 return (*Connection())->CheckTableExist(name);
301 #endif // DPL_THREAD_DATABASE_SUPPORT_H