OpenASIP 2.2
Loading...
Searching...
No Matches
SQLiteConnection.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2014 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file SQLiteConnection.cc
26 *
27 * Implementation of SQLiteConnection class.
28 *
29 * @author Pekka Jääskeläinen 2004 (pekka.jaaskelainen-no.spam-tut.fi)
30 *
31 * @note rating: red
32 */
33
34#include <string>
35using std::string;
36
37#include "SQLiteConnection.hh"
38#include "SQLiteQueryResult.hh"
39
40/**
41 * Constructor.
42 *
43 * @param connection A pointer to a SQLite connection handle.
44 */
46 connection_(connection), transactionActive_(false) {
47}
48
49/**
50 * Destructor.
51 *
52 * Closes the connection.
53 */
57
58/**
59 * Performs a query that changes the database (UPDATE/INSERT/DELETE).
60 *
61 * Does not autocommit the changes in case the update is in the middle of
62 * transaction.
63 *
64 * @param queryString The query string.
65 * @return Number of rows affected by the change.
66 * @exception RelationalDBException In case a database error occured.
67 */
68int
69SQLiteConnection::updateQuery(const std::string& queryString) {
70 if (connection_ == NULL) {
72 __FILE__, __LINE__, "SQLiteConnection::updateQuery()",
73 "Not connected!");
74 }
75
76 // "virtual machine" used by SQLite to execute the statements
77 sqlite3_stmt* stmt = compileQuery(queryString);
78
79 assert(stmt != NULL);
80
81 throwIfSQLiteError(sqlite3_step(stmt));
82 finalizeQuery(stmt);
83
84 return sqlite3_changes(connection_);
85}
86
87/**
88 * Performs a SQL Data Definition Language query, that is a query that may
89 * change the structure of the database (CREATE TABLE, etc.).
90 *
91 * Does not autocommit the changes in case the update is in the middle of
92 * transaction.
93 *
94 * @param queryString The query string.
95 * @exception RelationalDBException In case a database error occured.
96 */
97void
98SQLiteConnection::DDLQuery(const std::string& queryString) {
99 updateQuery(queryString);
100}
101
102/**
103 * Performs a data retrieval query (SELECT).
104 *
105 * @param queryString The query string.
106 * @return A handle to the query result set.
107 * @exception RelationalDBException In case a database error occured.
108 */
110SQLiteConnection::query(const std::string& queryString, bool init) {
111 sqlite3_stmt* stmt = compileQuery(queryString);
112 SQLiteQueryResult* result = new SQLiteQueryResult(stmt, this, init);
113 return result;
114}
115
116/**
117 * Starts a new database transaction.
118 *
119 * Also ends the possible previous transaction successfully (commit).
120 *
121 * @exception RelationalDBException In case a database error occured.
122 */
123void
125 if (transactionActive_) {
126 commit();
127 }
128 updateQuery("BEGIN;");
129 transactionActive_ = true;
130}
131
132/**
133 * Ends the current database transaction unsuccessfully and rollbacks all
134 * the changes the queries in the transaction would have done.
135 *
136 * @exception RelationalDBException In case a database error occured.
137 */
138void
140 updateQuery("ROLLBACK;");
141 transactionActive_ = false;
142}
143
144/**
145 * Ends the current database transaction successfully and commits all
146 * the changes in the transaction to the database.
147 *
148 * @exception RelationalDBException In case a database error occured.
149 */
150void
152 updateQuery("COMMIT;");
153 transactionActive_ = false;
154}
155
156/**
157 * Returns the row ID of the most recent insert in the database.
158 *
159 * @return The row ID.
160 */
161RowID
163 return sqlite3_last_insert_rowid(connection_);
164}
165
166
167/**
168 * Checks if database has given table by name.
169 *
170 * @param tableName Name of the table
171 * @return True if db has the table. Otherwise false.
172 * @exception RelationalDBException In case a database error occurred or
173 * call was made in the middle of an active
174 * transaction.
175 */
176bool
177SQLiteConnection::tableExistsInDB(const std::string& tableName) {
178 if (transactionActive_) {
179 throw RelationalDBException(__FILE__, __LINE__,
180 "SQLiteConnection::tableExistsInDB()",
181 "Illegal call during active transaction.");
182 }
183
184 string query = "SELECT count(*) "
185 "FROM sqlite_master "
186 "WHERE type = 'table' and name = '" + tableName + "';";
187
188 RelationalDBQueryResult* result = this->query(query, false);
189 assert(result->hasNext());
190 result->next();
191 const DataObject& count = result->data(0);
192
193 int intBoolValue = 0;
194
195 try {
196 intBoolValue = count.integerValue(); // boolValue is zero if DataObject
197 // has NULL value.
198 } catch (NumberFormatException& e) {
199 throw RelationalDBException(__FILE__, __LINE__,
200 "SQLiteConnection::tableExistsInDB()",
201 "Exception from DataObject: " + e.errorMessage());
202 }
203
204 delete result;
205 return intBoolValue;
206}
207
208/**
209 * Return number of entries in the given table.
210 *
211 * @param tableName Name of the table.
212 * @return Number of entries in table.
213 * @exception RelationalDBException In case a database error occurred,
214 * call was made in the middle of an active transaction or the table does not
215 * exists.
216 */
217int
218SQLiteConnection::rowCountInTable(const std::string& tableName) {
219 if (!tableExistsInDB(tableName)) {
220 throw RelationalDBException(__FILE__, __LINE__,
221 "SQLiteConnection::rowCountInTable()",
222 "Table was not found.");
223 }
224 string query = "SELECT count(*) FROM " + tableName + ";";
225
226 RelationalDBQueryResult* result = this->query(query, false);
227 assert(result->hasNext());
228 result->next();
229 const DataObject& count = result->data(0);
230 int countAsInt = -1;
231
232 try {
233 countAsInt = count.integerValue(); // boolValue is zero if DataObject
234 // has NULL value.
235 } catch (NumberFormatException& e) {
236 throw RelationalDBException(__FILE__, __LINE__,
237 "SQLiteConnection::tableExistsInDB()",
238 "Exception from DataObject: " + e.errorMessage());
239 }
240
241 delete result;
242 assert(countAsInt > -1);
243 return countAsInt;
244}
245
246/**
247 * Throws a RelationalDBException if result value indicates an SQLite error.
248 *
249 * @param result The value from a SQLite API call.
250 * @exception RelationalDBException Thrown if result is not SQLITE_OK.
251 */
252void
254 if (result != SQLITE_OK && result != SQLITE_ROW &&
255 result != SQLITE_DONE) {
256
257 string error = sqlite3_errmsg(connection_);
258 throw RelationalDBException(__FILE__, __LINE__, "", error);
259 }
260}
261
262/**
263 * Compiles a SQLite query.
264 *
265 * @param queryString The SQL statement to compile.
266 * @return The SQLite virtual machine that should be used to execute the query.
267 * @exception RelationalDBException In case a database error occured.
268 */
269sqlite3_stmt*
270SQLiteConnection::compileQuery(const std::string& queryString) {
271 // "virtual machine" used by SQLite to execute the statements
272 sqlite3_stmt* stmt = NULL;
273 const char* dummy = NULL;
274
275 throwIfSQLiteError(sqlite3_prepare(
276 connection_, queryString.c_str(), queryString.length(),
277 &stmt, &dummy));
278 return stmt;
279}
280
281/**
282 * Finalizes a SQLite query, frees the virtual machine.
283 *
284 * Does nothing if the statement is NULL.
285 *
286 * @param statement The SQLite statement to free.
287 * @exception RelationalDBException In case there was errors (can be
288 * cumulated from a previous sqlite3_step() call).
289 */
290void
291SQLiteConnection::finalizeQuery(sqlite3_stmt* statement) {
292 if (statement == NULL) {
293 return;
294 }
295
296 throwIfSQLiteError(sqlite3_finalize(statement));
297}
298
299/**
300* Return database version number.
301*
302* @return Database version.
303*/
304int
306 int version = 0;
307
308 string query = "pragma user_version;";
309
310 RelationalDBQueryResult* result = this->query(query, false);
311
312
313 assert(result->hasNext());
314 result->next();
315 const DataObject& count = result->data(0);
316
317 try {
318 version = count.integerValue();
319 } catch (NumberFormatException& e) {
320 throw RelationalDBException(__FILE__, __LINE__,
321 "SQLiteConnection::version()",
322 "Exception from DataObject: " + e.errorMessage());
323 }
324
325 delete result;
326 return version;
327}
328
329/**
330* Set database version number.
331*
332* @param version New database version.
333*/
334void
336 string query = "pragma user_version = " +
337 std::to_string(version) + ";";
338 this->updateQuery(query);
339}
#define assert(condition)
int RowID
Type definition of row ID in relational databases.
Definition DBTypes.hh:37
find Finds info of the inner loops in the false
SimValue dummy(32)
a dummy simvalue which is given for operands that are not bound
virtual int integerValue() const
std::string errorMessage() const
Definition Exception.cc:123
virtual const DataObject & data(std::size_t column) const =0
SQLiteConnection(sqlite3 *connection)
virtual bool tableExistsInDB(const std::string &tableName)
virtual void commit()
virtual RowID lastInsertRowID()
virtual void rollback()
virtual ~SQLiteConnection()
void finalizeQuery(sqlite3_stmt *statement)
sqlite3_stmt * compileQuery(const std::string &queryString)
sqlite3 * connection_
SQLite connection handle is saved to this.
virtual void DDLQuery(const std::string &queryString)
void throwIfSQLiteError(int result)
virtual void beginTransaction()
virtual int rowCountInTable(const std::string &tableName)
virtual int updateQuery(const std::string &queryString)
virtual int version()
virtual void updateVersion(int version)
virtual RelationalDBQueryResult * query(const std::string &queryString, bool init=true)