Пример #1
0
static int dbd_sqlite3_select(apr_pool_t *pool, apr_dbd_t *sql,
                              apr_dbd_results_t **results, const char *query,
                              int seek)
{
    sqlite3_stmt *stmt = NULL;
    const char *tail = NULL;
    int ret;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    apr_dbd_mutex_lock();

    ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
    if (dbd_sqlite3_is_success(ret)) {
        ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek);
    }
    sqlite3_finalize(stmt);

    apr_dbd_mutex_unlock();

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }
    return ret;
}
Пример #2
0
static int dbd_sqlite3_query(apr_dbd_t *sql, int *nrows, const char *query)
{
    sqlite3_stmt *stmt = NULL;
    const char *tail = NULL;
    int ret = -1, length = 0;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    length = strlen(query);
#if APR_HAS_THREADS
    apr_thread_mutex_lock(sql->mutex);
#endif

    do {
        int retry_count = 0;

        ret = sqlite3_prepare(sql->conn, query, length, &stmt, &tail);
        if (ret != SQLITE_OK) {
            sqlite3_finalize(stmt);
            break;
        }

        while(retry_count++ <= MAX_RETRY_COUNT) {
            ret = sqlite3_step(stmt);
            if (ret != SQLITE_BUSY)
                break;

#if APR_HAS_THREADS
            apr_thread_mutex_unlock(sql->mutex);
#endif
            apr_sleep(MAX_RETRY_SLEEP);
#if APR_HAS_THREADS
            apr_thread_mutex_lock(sql->mutex);
#endif
        }

        *nrows = sqlite3_changes(sql->conn);
        sqlite3_finalize(stmt);
        length -= (tail - query);
        query = tail;
    } while (length > 0);

    if (dbd_sqlite3_is_success(ret)) {
        ret = 0;
    }
#if APR_HAS_THREADS
    apr_thread_mutex_unlock(sql->mutex);
#endif
    if (sql->trans) {
        sql->trans->errnum = ret;
    }
    return ret;
}
Пример #3
0
static int dbd_sqlite3_pquery(apr_pool_t *pool, apr_dbd_t *sql,
                              int *nrows, apr_dbd_prepared_t *statement,
                              int nargs, const char **values)
{
    sqlite3_stmt *stmt = statement->stmt;
    int ret = -1, retry_count = 0, i;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

#if APR_HAS_THREADS
    apr_thread_mutex_lock(sql->mutex);
#endif

    ret = sqlite3_reset(stmt);
    if (ret == SQLITE_OK) {
        for (i=0; i < nargs; i++) {
            sqlite3_bind_text(stmt, i + 1, values[i], strlen(values[i]),
                              SQLITE_STATIC);
        }

        while(retry_count++ <= MAX_RETRY_COUNT) {
            ret = sqlite3_step(stmt);
            if (ret != SQLITE_BUSY)
                break;

#if APR_HAS_THREADS
            apr_thread_mutex_unlock(sql->mutex);
#endif
            apr_sleep(MAX_RETRY_SLEEP);
#if APR_HAS_THREADS
            apr_thread_mutex_lock(sql->mutex);
#endif
        }

        *nrows = sqlite3_changes(sql->conn);

        sqlite3_reset(stmt);
    }

    if (dbd_sqlite3_is_success(ret)) {
        ret = 0;
    }
#if APR_HAS_THREADS
    apr_thread_mutex_unlock(sql->mutex);
#endif
    if (sql->trans) {
        sql->trans->errnum = ret;
    }

    return ret;
}
Пример #4
0
static int dbd_sqlite3_query_internal(apr_dbd_t *sql, sqlite3_stmt *stmt,
                                      int *nrows)
{
    int ret = -1, retry_count = 0;

    while(retry_count++ <= MAX_RETRY_COUNT) {
        ret = sqlite3_step(stmt);
        if (ret != SQLITE_BUSY)
            break;

        apr_dbd_mutex_unlock();
        apr_sleep(MAX_RETRY_SLEEP);
        apr_dbd_mutex_lock();
    }

    *nrows = sqlite3_changes(sql->conn);

    if (dbd_sqlite3_is_success(ret)) {
        ret = 0;
    }
    return ret;
}
Пример #5
0
static int dbd_sqlite3_select_internal(apr_pool_t *pool,
                                       apr_dbd_t *sql,
                                       apr_dbd_results_t **results,
                                       sqlite3_stmt *stmt, int seek)
{
    int ret, retry_count = 0, column_count;
    size_t i, num_tuples = 0;
    int increment = 0;
    apr_dbd_row_t *row = NULL;
    apr_dbd_row_t *lastrow = NULL;
    apr_dbd_column_t *column;
    char *hold = NULL;

    column_count = sqlite3_column_count(stmt);
    if (!*results) {
        *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
    }
    (*results)->stmt = stmt;
    (*results)->sz = column_count;
    (*results)->random = seek;
    (*results)->next_row = 0;
    (*results)->tuples = 0;
    (*results)->col_names = apr_pcalloc(pool, column_count * sizeof(char *));
    (*results)->pool = pool;
    do {
        ret = sqlite3_step(stmt);
        if (ret == SQLITE_BUSY) {
            if (retry_count++ > MAX_RETRY_COUNT) {
                ret = SQLITE_ERROR;
            } else {
                apr_dbd_mutex_unlock();
                apr_sleep(MAX_RETRY_SLEEP);
                apr_dbd_mutex_lock();
            }
        } else if (ret == SQLITE_ROW) {
            int length;
            apr_dbd_column_t *col;
            row = apr_palloc(pool, sizeof(apr_dbd_row_t));
            row->res = *results;
            increment = sizeof(apr_dbd_column_t *);
            length = increment * (*results)->sz;
            row->columns = apr_palloc(pool, length);
            row->columnCount = column_count;
            for (i = 0; i < (*results)->sz; i++) {
                column = apr_palloc(pool, sizeof(apr_dbd_column_t));
                row->columns[i] = column;
                /* copy column name once only */
                if ((*results)->col_names[i] == NULL) {
                    (*results)->col_names[i] =
                        apr_pstrdup(pool, sqlite3_column_name(stmt, i));
                }
                column->name = (*results)->col_names[i];
                column->size = sqlite3_column_bytes(stmt, i);
                column->type = sqlite3_column_type(stmt, i);
                column->value = NULL;
                switch (column->type) {
                case SQLITE_FLOAT:
                case SQLITE_INTEGER:
                case SQLITE_TEXT:
                    hold = (char *) sqlite3_column_text(stmt, i);
                    if (hold) {
                        column->value = apr_pstrmemdup(pool, hold,
                                                       column->size);
                    }
                    break;
                case SQLITE_BLOB:
                    hold = (char *) sqlite3_column_blob(stmt, i);
                    if (hold) {
                        column->value = apr_pstrmemdup(pool, hold,
                                                       column->size);
                    }
                    break;
                case SQLITE_NULL:
                    break;
                }
                col = row->columns[i];
            }
            row->rownum = num_tuples++;
            row->next_row = 0;
            (*results)->tuples = num_tuples;
            if ((*results)->next_row == 0) {
                (*results)->next_row = row;
            }
            if (lastrow != 0) {
                lastrow->next_row = row;
            }
            lastrow = row;
        }
    } while (ret == SQLITE_ROW || ret == SQLITE_BUSY);

    if (dbd_sqlite3_is_success(ret)) {
        ret = 0;
    }
    return ret;
}
Пример #6
0
static int dbd_sqlite3_select(apr_pool_t * pool, apr_dbd_t * sql, apr_dbd_results_t ** results, const char *query, int seek)
{
    sqlite3_stmt *stmt = NULL;
    const char *tail = NULL;
    int i, ret, retry_count = 0;
    size_t num_tuples = 0;
    int increment = 0;
    apr_dbd_row_t *row = NULL;
    apr_dbd_row_t *lastrow = NULL;
    apr_dbd_column_t *column;
    char *hold = NULL;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

#if APR_HAS_THREADS
    apr_thread_mutex_lock(sql->mutex);
#endif

    ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
    if (!dbd_sqlite3_is_success(ret)) {
#if APR_HAS_THREADS
        apr_thread_mutex_unlock(sql->mutex);
#endif
        return ret;
    } else {
        int column_count;
        column_count = sqlite3_column_count(stmt);
        if (!*results) {
            *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
        }
        (*results)->stmt = stmt;
        (*results)->sz = column_count;
        (*results)->random = seek;
        (*results)->next_row = 0;
        (*results)->tuples = 0;
        (*results)->col_names = apr_pcalloc(pool,
                                            column_count * sizeof(char *));
        do {
            ret = sqlite3_step(stmt);
            if (ret == SQLITE_BUSY) {
                if (retry_count++ > MAX_RETRY_COUNT) {
                    ret = SQLITE_ERROR;
                } else {
#if APR_HAS_THREADS
                    apr_thread_mutex_unlock(sql->mutex);
#endif
                    apr_sleep(MAX_RETRY_SLEEP);
#if APR_HAS_THREADS
                    apr_thread_mutex_lock(sql->mutex);
#endif
                }
            } else if (ret == SQLITE_ROW) {
                int length;
                apr_dbd_column_t *col;
                row = apr_palloc(pool, sizeof(apr_dbd_row_t));
                row->res = *results;
                increment = sizeof(apr_dbd_column_t *);
                length = increment * (*results)->sz;
                row->columns = apr_palloc(pool, length);
                row->columnCount = column_count;
                for (i = 0; i < (*results)->sz; i++) {
                    column = apr_palloc(pool, sizeof(apr_dbd_column_t));
                    row->columns[i] = column;
                    /* copy column name once only */
                    if ((*results)->col_names[i] == NULL) {
                      (*results)->col_names[i] =
                          apr_pstrdup(pool, sqlite3_column_name(stmt, i));
                    }
                    column->name = (*results)->col_names[i];
                    column->size = sqlite3_column_bytes(stmt, i);
                    column->type = sqlite3_column_type(stmt, i);
                    column->value = NULL;
                    switch (column->type) {
                    case SQLITE_FLOAT:
                    case SQLITE_INTEGER:
                    case SQLITE_TEXT:
                        hold = NULL;
                        hold = (char *) sqlite3_column_text(stmt, i);
                        if (hold) {
                            column->value = apr_palloc(pool, column->size + 1);
                            strncpy(column->value, hold, column->size + 1);
                        }
                        break;
                    case SQLITE_BLOB:
                        break;
                    case SQLITE_NULL:
                        break;
                    }
                    col = row->columns[i];
                }
                row->rownum = num_tuples++;
                row->next_row = 0;
                (*results)->tuples = num_tuples;
                if ((*results)->next_row == 0) {
                    (*results)->next_row = row;
                }
                if (lastrow != 0) {
                    lastrow->next_row = row;
                }
                lastrow = row;
            } else if (ret == SQLITE_DONE) {
                ret = SQLITE_OK;
            }
        } while (ret == SQLITE_ROW || ret == SQLITE_BUSY);
    }
    ret = sqlite3_finalize(stmt);
#if APR_HAS_THREADS
    apr_thread_mutex_unlock(sql->mutex);
#endif

    if (sql->trans) {
        sql->trans->errnum = ret;
    }
    return ret;
}