Created
April 5, 2011 06:45
-
-
Save alexeyr/903137 to your computer and use it in GitHub Desktop.
Weirdness
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| static void sql_exec_one_statement( | |
| sqlite3_stmt *statement, async_sqlite3_command *async_command, | |
| int *term_count_p, int *term_allocated_p, ErlDrvTermData **dataset_p) { | |
| int column_count = sqlite3_column_count(statement); | |
| int row_count = 0, next_row; | |
| int base_term_count; | |
| sqlite3_drv_t *drv = async_command->driver_data; | |
| ptr_list **ptrs_p = &(async_command->ptrs); | |
| ptr_list **binaries_p = &(async_command->binaries); | |
| // printf("\nStart of sql_exec_one_statement: term_count=%d, term_allocated=%d", *term_count_p, *term_allocated_p); | |
| int i; | |
| if (column_count > 0) { | |
| *term_count_p += 2; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM; | |
| (*dataset_p)[*term_count_p - 1] = drv->atom_columns; | |
| base_term_count = *term_count_p; | |
| get_columns( | |
| drv, statement, column_count, base_term_count, term_count_p, term_allocated_p, dataset_p); | |
| *term_count_p += 4; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[base_term_count + column_count * 3 + 3] = ERL_DRV_TUPLE; | |
| (*dataset_p)[base_term_count + column_count * 3 + 4] = 2; | |
| (*dataset_p)[base_term_count + column_count * 3 + 5] = ERL_DRV_ATOM; | |
| (*dataset_p)[base_term_count + column_count * 3 + 6] = drv->atom_rows; | |
| // printf("\nAfter adding columns: column_count=%d, term_count=%d, term_allocated=%d", column_count, *term_count_p, *term_allocated_p); | |
| } | |
| #ifdef DEBUG | |
| fprintf(drv->log, "Exec: %s\n", sqlite3_sql(statement)); | |
| fflush(drv->log); | |
| #endif | |
| while ((next_row = sqlite3_step(statement)) == SQLITE_ROW) { | |
| for (i = 0; i < column_count; i++) { | |
| #ifdef DEBUG | |
| fprintf(drv->log, "Column %d type: %d\n", i, sqlite3_column_type(statement, i)); | |
| fflush(drv->log); | |
| #endif | |
| switch (sqlite3_column_type(statement, i)) { | |
| case SQLITE_INTEGER: { | |
| ErlDrvSInt64 *int64_ptr = driver_alloc(sizeof(ErlDrvSInt64)); | |
| *int64_ptr = (ErlDrvSInt64) sqlite3_column_int64(statement, i); | |
| *ptrs_p = add_to_ptr_list(*ptrs_p, int64_ptr); | |
| *term_count_p += 2; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_INT64; | |
| (*dataset_p)[*term_count_p - 1] = (ErlDrvTermData) int64_ptr; | |
| break; | |
| } | |
| case SQLITE_FLOAT: { | |
| double *float_ptr = driver_alloc(sizeof(double)); | |
| *float_ptr = sqlite3_column_double(statement, i); | |
| *ptrs_p = add_to_ptr_list(*ptrs_p, float_ptr); | |
| *term_count_p += 2; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_FLOAT; | |
| (*dataset_p)[*term_count_p - 1] = (ErlDrvTermData) float_ptr; | |
| break; | |
| } | |
| case SQLITE_BLOB: { | |
| int bytes = sqlite3_column_bytes(statement, i); | |
| ErlDrvBinary* binary = driver_alloc_binary(bytes); | |
| binary->orig_size = bytes; | |
| memcpy(binary->orig_bytes, | |
| sqlite3_column_blob(statement, i), bytes); | |
| *binaries_p = add_to_ptr_list(*binaries_p, binary); | |
| *term_count_p += 8; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 8] = ERL_DRV_ATOM; | |
| (*dataset_p)[*term_count_p - 7] = drv->atom_blob; | |
| (*dataset_p)[*term_count_p - 6] = ERL_DRV_BINARY; | |
| (*dataset_p)[*term_count_p - 5] = (ErlDrvTermData) binary; | |
| (*dataset_p)[*term_count_p - 4] = bytes; | |
| (*dataset_p)[*term_count_p - 3] = 0; | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE; | |
| (*dataset_p)[*term_count_p - 1] = 2; | |
| break; | |
| } | |
| case SQLITE_TEXT: { | |
| int bytes = sqlite3_column_bytes(statement, i); | |
| ErlDrvBinary* binary = driver_alloc_binary(bytes); | |
| binary->orig_size = bytes; | |
| memcpy(binary->orig_bytes, | |
| sqlite3_column_blob(statement, i), bytes); | |
| *binaries_p = add_to_ptr_list(*binaries_p, binary); | |
| *term_count_p += 4; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 4] = ERL_DRV_BINARY; | |
| (*dataset_p)[*term_count_p - 3] = (ErlDrvTermData) binary; | |
| (*dataset_p)[*term_count_p - 2] = bytes; | |
| (*dataset_p)[*term_count_p - 1] = 0; | |
| break; | |
| } | |
| case SQLITE_NULL: { | |
| *term_count_p += 2; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM; | |
| (*dataset_p)[*term_count_p - 1] = drv->atom_null; | |
| break; | |
| } | |
| } | |
| } | |
| *term_count_p += 2; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE; | |
| (*dataset_p)[*term_count_p - 1] = column_count; | |
| row_count++; | |
| } | |
| if (next_row == SQLITE_BUSY) { | |
| return_error(drv, SQLITE_BUSY, "SQLite3 database is busy", | |
| &async_command->dataset, &async_command->term_count, | |
| &async_command->error_code); | |
| return; | |
| } | |
| if (next_row != SQLITE_DONE) { | |
| return_error(drv, next_row, sqlite3_errmsg(drv->db), | |
| &async_command->dataset, &async_command->term_count, | |
| &async_command->error_code); | |
| return; | |
| } | |
| printf("\nAfter adding rows: column_count=%d, term_count=%d, term_allocated=%d", column_count, *term_count_p, *term_allocated_p); | |
| if (column_count > 0) { | |
| *term_count_p += 3+2+3; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 8] = ERL_DRV_NIL; | |
| (*dataset_p)[*term_count_p - 7] = ERL_DRV_LIST; | |
| (*dataset_p)[*term_count_p - 6] = row_count + 1; | |
| (*dataset_p)[*term_count_p - 5] = ERL_DRV_TUPLE; | |
| (*dataset_p)[*term_count_p - 4] = 2; | |
| (*dataset_p)[*term_count_p - 3] = ERL_DRV_NIL; | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_LIST; | |
| (*dataset_p)[*term_count_p - 1] = 3; | |
| printf("\nEnd if branch 1"); | |
| } else if (sql_is_insert(sqlite3_sql(statement))) { | |
| ErlDrvSInt64 *rowid_ptr = driver_alloc(sizeof(ErlDrvSInt64)); | |
| *rowid_ptr = (ErlDrvSInt64) sqlite3_last_insert_rowid(drv->db); | |
| *ptrs_p = add_to_ptr_list(*ptrs_p, rowid_ptr); | |
| *term_count_p += 6; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 6] = ERL_DRV_ATOM; | |
| (*dataset_p)[*term_count_p - 5] = drv->atom_rowid; | |
| (*dataset_p)[*term_count_p - 4] = ERL_DRV_INT64; | |
| (*dataset_p)[*term_count_p - 3] = (ErlDrvTermData) rowid_ptr; | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE; | |
| (*dataset_p)[*term_count_p - 1] = 2; | |
| } else { | |
| *term_count_p += 2; | |
| if (*term_count_p > *term_allocated_p) { | |
| *term_allocated_p = max(*term_count_p, *term_allocated_p*2); | |
| *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); | |
| } | |
| (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM; | |
| (*dataset_p)[*term_count_p - 1] = drv->atom_ok; | |
| } | |
| printf("\nEnd if"); | |
| printf("\nEnd of sql_exec_one_statement"); | |
| #ifdef DEBUG | |
| fprintf(drv->log, "Total term count: %p %d, rows count: %dx%d\n", statement, *term_count_p, column_count, row_count); | |
| fflush(drv->log); | |
| #endif | |
| async_command->finalize_statement_on_free = 1; | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just buffered IO, nothing to see here.