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