Annotation of embedaddon/strongswan/src/libstrongswan/plugins/sqlite/sqlite_database.c, revision 1.1.1.1

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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>