This commit is contained in:
sergey-miryanov
2011-04-28 08:44:54 +06:00
3 changed files with 97 additions and 70 deletions

View File

@@ -365,20 +365,24 @@ static inline int decode_and_bind_param(
case ERL_BINARY_EXT: case ERL_BINARY_EXT:
char_buf_val = driver_alloc(*p_size * sizeof(char)); char_buf_val = driver_alloc(*p_size * sizeof(char));
ei_decode_binary(buffer, p_index, char_buf_val, &bin_size); ei_decode_binary(buffer, p_index, char_buf_val, &bin_size);
// assert(bin_size == *p_size)
result = sqlite3_bind_text(statement, param_index, char_buf_val, *p_size, &driver_free_fun); result = sqlite3_bind_text(statement, param_index, char_buf_val, *p_size, &driver_free_fun);
break; break;
case ERL_SMALL_TUPLE_EXT: case ERL_SMALL_TUPLE_EXT:
// assume this is {blob, Blob} // assume this is {blob, Blob}
ei_get_type(buffer, p_index, p_type, p_size); ei_get_type(buffer, p_index, p_type, p_size);
ei_decode_tuple_header(buffer, p_index, p_size); ei_decode_tuple_header(buffer, p_index, p_size);
assert (*p_size == 2); if (*p_size != 2) {
output_error(drv, SQLITE_MISUSE, "bad parameter type");
return 1;
}
ei_skip_term(buffer, p_index); // skipped the atom 'blob' ei_skip_term(buffer, p_index); // skipped the atom 'blob'
ei_get_type(buffer, p_index, p_type, p_size); ei_get_type(buffer, p_index, p_type, p_size);
assert (*p_type == ERL_BINARY_EXT); if (*p_type != ERL_BINARY_EXT) {
output_error(drv, SQLITE_MISUSE, "bad parameter type");
return 1;
}
char_buf_val = driver_alloc(*p_size * sizeof(char)); char_buf_val = driver_alloc(*p_size * sizeof(char));
ei_decode_binary(buffer, p_index, char_buf_val, &bin_size); ei_decode_binary(buffer, p_index, char_buf_val, &bin_size);
// assert(bin_size == *p_size)
result = sqlite3_bind_blob(statement, param_index, char_buf_val, *p_size, &driver_free_fun); result = sqlite3_bind_blob(statement, param_index, char_buf_val, *p_size, &driver_free_fun);
break; break;
default: default:
@@ -399,9 +403,29 @@ static int bind_parameters(
int i, cur_list_size = -1, param_index = 1, param_indices_are_explicit = 0, result = 0; int i, cur_list_size = -1, param_index = 1, param_indices_are_explicit = 0, result = 0;
long param_index_long; long param_index_long;
char param_name[MAXATOMLEN + 1]; // parameter names shouldn't be longer than 256! char param_name[MAXATOMLEN + 1]; // parameter names shouldn't be longer than 256!
while (*p_index < buffer_size) { char *acc_string;
ei_decode_list_header(buffer, p_index, &cur_list_size); result = ei_decode_list_header(buffer, p_index, &cur_list_size);
if (result) {
// probably all parameters are integers between 0 and 255
// and the list was encoded as string (see ei documentation)
ei_get_type(buffer, p_index, p_type, p_size);
if (*p_type != ERL_STRING_EXT) {
return output_error(drv, SQLITE_ERROR,
"error while binding parameters");
}
acc_string = driver_alloc(sizeof(char*) * (*p_size + 1));
ei_decode_string(buffer, p_index, acc_string);
for (param_index = 1; param_index <= *p_size; param_index++) {
sqlite3_bind_int(statement, param_index, (int) acc_string[param_index - 1]);
}
driver_free(acc_string);
return 0;
}
for (i = 0; i < cur_list_size; i++) { for (i = 0; i < cur_list_size; i++) {
if (*p_index >= buffer_size) {
return output_error(drv, SQLITE_ERROR,
"error while binding parameters");
}
ei_get_type(buffer, p_index, p_type, p_size); ei_get_type(buffer, p_index, p_type, p_size);
if (*p_type == ERL_SMALL_TUPLE_EXT) { if (*p_type == ERL_SMALL_TUPLE_EXT) {
int old_index = *p_index; int old_index = *p_index;
@@ -470,7 +494,6 @@ static int bind_parameters(
++param_index; ++param_index;
} }
} }
}
return result; return result;
} }
@@ -516,7 +539,7 @@ static int sql_bind_and_exec(sqlite3_drv_t *drv, char *buffer, int buffer_size)
ei_decode_version(buffer, &index, NULL); ei_decode_version(buffer, &index, NULL);
result = ei_decode_tuple_header(buffer, &index, &size); result = ei_decode_tuple_header(buffer, &index, &size);
if (size != 2) { if (result || (size != 2)) {
return output_error(drv, SQLITE_MISUSE, return output_error(drv, SQLITE_MISUSE,
"Expected a tuple of SQL command and params"); "Expected a tuple of SQL command and params");
} }
@@ -1019,7 +1042,7 @@ POPULATE_COMMAND:
async_command->binaries = binaries; async_command->binaries = binaries;
async_command->row_count = 1; async_command->row_count = 1;
#ifdef DEBUG #ifdef DEBUG
fprintf(drv->log, "Total term count: %p %d, columns count: %dx%d\n", statement, term_count, column_count); fprintf(drv->log, "Total term count: %p %d, columns count: %d\n", statement, term_count, column_count);
fflush(drv->log); fflush(drv->log);
#endif #endif
} }

View File

@@ -1,7 +1,7 @@
{application, sqlite3, {application, sqlite3,
[ [
{description, "SQLite3 Interface"}, {description, "SQLite3 Interface"},
{vsn, "1.0"}, {vsn, "1.0.1"},
{modules, []}, {modules, []},
{registered, []}, {registered, []},
{applications, [kernel, stdlib]}, {applications, [kernel, stdlib]},

View File

@@ -47,7 +47,8 @@ all_test_() ->
?FuncTest(select_many_records), ?FuncTest(select_many_records),
?FuncTest(nonexistent_table_info), ?FuncTest(nonexistent_table_info),
?FuncTest(large_number), ?FuncTest(large_number),
?FuncTest(unicode)]}. ?FuncTest(unicode),
?FuncTest(acc_string_encoding)]}.
open_db() -> open_db() ->
sqlite3:open(ct, [in_memory]). sqlite3:open(ct, [in_memory]).
@@ -216,6 +217,9 @@ unicode() ->
sqlite3:write(ct, unicode, [{str, UnicodeString}]), sqlite3:write(ct, unicode, [{str, UnicodeString}]),
?assertEqual([{unicode:characters_to_binary(UnicodeString)}], rows(sqlite3:read_all(ct, unicode))). ?assertEqual([{unicode:characters_to_binary(UnicodeString)}], rows(sqlite3:read_all(ct, unicode))).
acc_string_encoding() ->
?assertEqual([{62}], rows(sqlite3:sql_exec(ct, "SELECT ? + ?", [30,32]))).
prepared_test() -> prepared_test() ->
Columns = ["id", "name", "age", "wage"], Columns = ["id", "name", "age", "wage"],
Abby = {1, <<"abby">>, 20, 2000}, Abby = {1, <<"abby">>, 20, 2000},