Return to sqlite_database.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / sqlite |
1.1 misho 1: /* 2: * Copyright (C) 2013 Tobias Brunner 3: * Copyright (C) 2007 Martin Willi 4: * HSR Hochschule fuer Technik Rapperswil 5: * 6: * This program is free software; you can redistribute it and/or modify it 7: * under the terms of the GNU General Public License as published by the 8: * Free Software Foundation; either version 2 of the License, or (at your 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 10: * 11: * This program is distributed in the hope that it will be useful, but 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14: * for more details. 15: */ 16: 17: #include "sqlite_database.h" 18: 19: #include <sqlite3.h> 20: #include <unistd.h> 21: #include <library.h> 22: #include <utils/debug.h> 23: #include <threading/mutex.h> 24: #include <threading/thread_value.h> 25: 26: typedef struct private_sqlite_database_t private_sqlite_database_t; 27: 28: /** 29: * private data of sqlite_database 30: */ 31: struct private_sqlite_database_t { 32: 33: /** 34: * public functions 35: */ 36: sqlite_database_t public; 37: 38: /** 39: * sqlite database connection 40: */ 41: sqlite3 *db; 42: 43: /** 44: * thread-specific transaction, as transaction_t 45: */ 46: thread_value_t *transaction; 47: 48: /** 49: * mutex used to lock execute(), if necessary 50: */ 51: mutex_t *mutex; 52: }; 53: 54: /** 55: * Database transaction 56: */ 57: typedef struct { 58: 59: /** 60: * Refcounter if transaction() is called multiple times 61: */ 62: refcount_t refs; 63: 64: /** 65: * TRUE if transaction was rolled back 66: */ 67: bool rollback; 68: 69: } transaction_t; 70: 71: /** 72: * Check if the SQLite library is thread safe 73: */ 74: static bool is_threadsafe() 75: { 76: #if SQLITE_VERSION_NUMBER >= 3005000 77: return sqlite3_threadsafe() > 0; 78: #endif 79: /* sqlite connections prior to 3.5 may be used by a single thread only */ 80: return FALSE; 81: } 82: 83: /** 84: * Create and run a sqlite stmt using a sql string and args 85: */ 86: static sqlite3_stmt* run(private_sqlite_database_t *this, char *sql, 87: va_list *args) 88: { 89: sqlite3_stmt *stmt = NULL; 90: int params, i, res = SQLITE_OK; 91: 92: #ifdef HAVE_SQLITE3_PREPARE_V2 93: if (sqlite3_prepare_v2(this->db, sql, -1, &stmt, NULL) == SQLITE_OK) 94: #else 95: if (sqlite3_prepare(this->db, sql, -1, &stmt, NULL) == SQLITE_OK) 96: #endif 97: { 98: params = sqlite3_bind_parameter_count(stmt); 99: for (i = 1; i <= params; i++) 100: { 101: switch (va_arg(*args, db_type_t)) 102: { 103: case DB_INT: 104: { 105: res = sqlite3_bind_int(stmt, i, va_arg(*args, int)); 106: break; 107: } 108: case DB_UINT: 109: { 110: res = sqlite3_bind_int64(stmt, i, va_arg(*args, u_int)); 111: break; 112: } 113: case DB_TEXT: 114: { 115: const char *text = va_arg(*args, const char*); 116: res = sqlite3_bind_text(stmt, i, text, -1, 117: SQLITE_TRANSIENT); 118: break; 119: } 120: case DB_BLOB: 121: { 122: chunk_t c = va_arg(*args, chunk_t); 123: res = sqlite3_bind_blob(stmt, i, c.ptr, c.len, 124: SQLITE_TRANSIENT); 125: break; 126: } 127: case DB_DOUBLE: 128: { 129: res = sqlite3_bind_double(stmt, i, va_arg(*args, double)); 130: break; 131: } 132: case DB_NULL: 133: { 134: res = sqlite3_bind_null(stmt, i); 135: break; 136: } 137: default: 138: { 139: res = SQLITE_MISUSE; 140: break; 141: } 142: } 143: if (res != SQLITE_OK) 144: { 145: break; 146: } 147: } 148: } 149: else 150: { 151: DBG1(DBG_LIB, "preparing sqlite statement failed: %s", 152: sqlite3_errmsg(this->db)); 153: } 154: if (res != SQLITE_OK) 155: { 156: DBG1(DBG_LIB, "binding sqlite statement failed: %s", 157: sqlite3_errmsg(this->db)); 158: sqlite3_finalize(stmt); 159: return NULL; 160: } 161: return stmt; 162: } 163: 164: typedef struct { 165: /** implements enumerator_t */ 166: enumerator_t public; 167: /** associated sqlite statement */ 168: sqlite3_stmt *stmt; 169: /** number of result columns */ 170: int count; 171: /** column types */ 172: db_type_t *columns; 173: /** back reference to parent */ 174: private_sqlite_database_t *database; 175: } sqlite_enumerator_t; 176: 177: METHOD(enumerator_t, sqlite_enumerator_destroy, void, 178: sqlite_enumerator_t *this) 179: { 180: sqlite3_finalize(this->stmt); 181: if (!is_threadsafe()) 182: { 183: this->database->mutex->unlock(this->database->mutex); 184: } 185: free(this->columns); 186: free(this); 187: } 188: 189: METHOD(enumerator_t, sqlite_enumerator_enumerate, bool, 190: sqlite_enumerator_t *this, va_list args) 191: { 192: int i; 193: 194: switch (sqlite3_step(this->stmt)) 195: { 196: case SQLITE_ROW: 197: break; 198: default: 199: DBG1(DBG_LIB, "stepping sqlite statement failed: %s", 200: sqlite3_errmsg(this->database->db)); 201: /* fall */ 202: case SQLITE_DONE: 203: return FALSE; 204: } 205: 206: for (i = 0; i < this->count; i++) 207: { 208: switch (this->columns[i]) 209: { 210: case DB_INT: 211: { 212: int *value = va_arg(args, int*); 213: *value = sqlite3_column_int(this->stmt, i); 214: break; 215: } 216: case DB_UINT: 217: { 218: u_int *value = va_arg(args, u_int*); 219: *value = (u_int)sqlite3_column_int64(this->stmt, i); 220: break; 221: } 222: case DB_TEXT: 223: { 224: const unsigned char **value = va_arg(args, const unsigned char**); 225: *value = sqlite3_column_text(this->stmt, i); 226: break; 227: } 228: case DB_BLOB: 229: { 230: chunk_t *chunk = va_arg(args, chunk_t*); 231: chunk->len = sqlite3_column_bytes(this->stmt, i); 232: chunk->ptr = (u_char*)sqlite3_column_blob(this->stmt, i); 233: break; 234: } 235: case DB_DOUBLE: 236: { 237: double *value = va_arg(args, double*); 238: *value = sqlite3_column_double(this->stmt, i); 239: break; 240: } 241: default: 242: DBG1(DBG_LIB, "invalid result type supplied"); 243: return FALSE; 244: } 245: } 246: return TRUE; 247: } 248: 249: METHOD(database_t, query, enumerator_t*, 250: private_sqlite_database_t *this, char *sql, ...) 251: { 252: sqlite3_stmt *stmt; 253: va_list args; 254: sqlite_enumerator_t *enumerator = NULL; 255: int i; 256: 257: if (!is_threadsafe()) 258: { 259: this->mutex->lock(this->mutex); 260: } 261: 262: va_start(args, sql); 263: stmt = run(this, sql, &args); 264: if (stmt) 265: { 266: INIT(enumerator, 267: .public = { 268: .enumerate = enumerator_enumerate_default, 269: .venumerate = _sqlite_enumerator_enumerate, 270: .destroy = _sqlite_enumerator_destroy, 271: }, 272: .stmt = stmt, 273: .count = sqlite3_column_count(stmt), 274: .database = this, 275: ); 276: enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count); 277: for (i = 0; i < enumerator->count; i++) 278: { 279: enumerator->columns[i] = va_arg(args, db_type_t); 280: } 281: } 282: va_end(args); 283: return (enumerator_t*)enumerator; 284: } 285: 286: METHOD(database_t, execute, int, 287: private_sqlite_database_t *this, int *rowid, char *sql, ...) 288: { 289: sqlite3_stmt *stmt; 290: int affected = -1; 291: va_list args; 292: 293: /* we need a lock to get our rowid/changes correctly */ 294: this->mutex->lock(this->mutex); 295: va_start(args, sql); 296: stmt = run(this, sql, &args); 297: va_end(args); 298: if (stmt) 299: { 300: if (sqlite3_step(stmt) == SQLITE_DONE) 301: { 302: if (rowid) 303: { 304: *rowid = sqlite3_last_insert_rowid(this->db); 305: } 306: affected = sqlite3_changes(this->db); 307: } 308: else 309: { 310: DBG1(DBG_LIB, "sqlite execute failed: %s", 311: sqlite3_errmsg(this->db)); 312: } 313: sqlite3_finalize(stmt); 314: } 315: this->mutex->unlock(this->mutex); 316: return affected; 317: } 318: 319: METHOD(database_t, transaction, bool, 320: private_sqlite_database_t *this, bool serializable) 321: { 322: transaction_t *trans; 323: char *cmd = serializable ? "BEGIN EXCLUSIVE TRANSACTION" 324: : "BEGIN TRANSACTION"; 325: 326: trans = this->transaction->get(this->transaction); 327: if (trans) 328: { 329: ref_get(&trans->refs); 330: return TRUE; 331: } 332: if (execute(this, NULL, cmd) == -1) 333: { 334: return FALSE; 335: } 336: INIT(trans, 337: .refs = 1, 338: ); 339: this->transaction->set(this->transaction, trans); 340: return TRUE; 341: } 342: 343: /** 344: * Finalize a transaction depending on the reference count and if it should be 345: * rolled back. 346: */ 347: static bool finalize_transaction(private_sqlite_database_t *this, 348: bool rollback) 349: { 350: transaction_t *trans; 351: char *command = "COMMIT TRANSACTION"; 352: bool success; 353: 354: trans = this->transaction->get(this->transaction); 355: if (!trans) 356: { 357: DBG1(DBG_LIB, "no database transaction found"); 358: return FALSE; 359: } 360: 361: if (ref_put(&trans->refs)) 362: { 363: if (trans->rollback) 364: { 365: command = "ROLLBACK TRANSACTION"; 366: } 367: success = execute(this, NULL, command) != -1; 368: 369: this->transaction->set(this->transaction, NULL); 370: free(trans); 371: return success; 372: } 373: else 374: { /* set flag, can't be unset */ 375: trans->rollback |= rollback; 376: } 377: return TRUE; 378: } 379: 380: METHOD(database_t, commit_, bool, 381: private_sqlite_database_t *this) 382: { 383: return finalize_transaction(this, FALSE); 384: } 385: 386: METHOD(database_t, rollback, bool, 387: private_sqlite_database_t *this) 388: { 389: return finalize_transaction(this, TRUE); 390: } 391: 392: METHOD(database_t, get_driver, db_driver_t, 393: private_sqlite_database_t *this) 394: { 395: return DB_SQLITE; 396: } 397: 398: /** 399: * Busy handler implementation 400: */ 401: static int busy_handler(private_sqlite_database_t *this, int count) 402: { 403: /* add a backoff time, quadratically increasing with every try */ 404: usleep(count * count * 1000); 405: /* always retry */ 406: return 1; 407: } 408: 409: METHOD(database_t, destroy, void, 410: private_sqlite_database_t *this) 411: { 412: if (sqlite3_close(this->db) == SQLITE_BUSY) 413: { 414: DBG1(DBG_LIB, "sqlite close failed because database is busy"); 415: } 416: this->transaction->destroy(this->transaction); 417: this->mutex->destroy(this->mutex); 418: free(this); 419: } 420: 421: /* 422: * see header file 423: */ 424: sqlite_database_t *sqlite_database_create(char *uri) 425: { 426: char *file; 427: private_sqlite_database_t *this; 428: 429: /** 430: * parse sqlite:///path/to/file.db uri 431: */ 432: if (!strpfx(uri, "sqlite://")) 433: { 434: return NULL; 435: } 436: file = uri + 9; 437: 438: INIT(this, 439: .public = { 440: .db = { 441: .query = _query, 442: .execute = _execute, 443: .transaction = _transaction, 444: .commit = _commit_, 445: .rollback = _rollback, 446: .get_driver = _get_driver, 447: .destroy = _destroy, 448: }, 449: }, 450: .mutex = mutex_create(MUTEX_TYPE_RECURSIVE), 451: .transaction = thread_value_create(NULL), 452: ); 453: 454: if (sqlite3_open(file, &this->db) != SQLITE_OK) 455: { 456: DBG1(DBG_LIB, "opening SQLite database '%s' failed: %s", 457: file, sqlite3_errmsg(this->db)); 458: destroy(this); 459: return NULL; 460: } 461: 462: sqlite3_busy_handler(this->db, (void*)busy_handler, this); 463: 464: return &this->public; 465: }