now can read table list from DB

This commit is contained in:
Max Lapshin
2009-10-14 01:00:08 +04:00
parent 4c66701aa0
commit be08fe62f3
3 changed files with 44 additions and 26 deletions

View File

@@ -107,7 +107,7 @@ static int sql_exec(sqlite3_drv_t *drv, char *command, int command_size) {
int i; int i;
fprintf(stderr, "Exec: %.*s\n", command_size, command); // fprintf(stderr, "Exec: %.*s\n", command_size, command);
result = sqlite3_prepare_v2(drv->db, command, command_size, &statement, (const char **)&rest); result = sqlite3_prepare_v2(drv->db, command, command_size, &statement, (const char **)&rest);
if(result != SQLITE_OK) { if(result != SQLITE_OK) {
@@ -117,27 +117,32 @@ static int sql_exec(sqlite3_drv_t *drv, char *command, int command_size) {
column_count = sqlite3_column_count(statement); column_count = sqlite3_column_count(statement);
dataset = NULL; dataset = NULL;
term_count += 2;
dataset = realloc(dataset, sizeof(*dataset) * term_count);
dataset[term_count - 2] = ERL_DRV_PORT;
dataset[term_count - 1] = driver_mk_port(drv->port);
while ((next_row = sqlite3_step(statement)) == SQLITE_ROW) { while ((next_row = sqlite3_step(statement)) == SQLITE_ROW) {
if (row_count == 0) { if (row_count == 0) {
int base = term_count; int base = term_count;
term_count += 2 + column_count*2 + 2 + 2 + 2; term_count += 2 + column_count*2 + 1 + 2 + 2 + 2;
dataset = realloc(dataset, sizeof(*dataset) * term_count); dataset = realloc(dataset, sizeof(*dataset) * term_count);
dataset[base] = ERL_DRV_ATOM; dataset[base] = ERL_DRV_ATOM;
dataset[base + 1] = driver_mk_atom("columns"); dataset[base + 1] = driver_mk_atom("columns");
for (i = 0; i < column_count; i++) { for (i = 0; i < column_count; i++) {
dataset[base + 2 + (i*2)] = ERL_DRV_ATOM; dataset[base + 2 + (i*2)] = ERL_DRV_ATOM;
fprintf(stderr, "Column: %s\n", sqlite3_column_name(statement, i)); // fprintf(stderr, "Column: %s\n", sqlite3_column_name(statement, i));
dataset[base + 2 + (i*2) + 1] = driver_mk_atom((char *)sqlite3_column_name(statement, i)); dataset[base + 2 + (i*2) + 1] = driver_mk_atom((char *)sqlite3_column_name(statement, i));
} }
dataset[base + 2 + column_count*2] = ERL_DRV_LIST; dataset[base + 2 + column_count*2 + 0] = ERL_DRV_NIL;
dataset[base + 2 + column_count*2 + 1] = column_count; dataset[base + 2 + column_count*2 + 1] = ERL_DRV_LIST;
dataset[base + 2 + column_count*2 + 2] = ERL_DRV_TUPLE; dataset[base + 2 + column_count*2 + 2] = column_count + 1;
dataset[base + 2 + column_count*2 + 3] = 2; dataset[base + 2 + column_count*2 + 3] = ERL_DRV_TUPLE;
dataset[base + 2 + column_count*2 + 4] = 2;
dataset[base + 2 + column_count*2 + 4] = ERL_DRV_ATOM; dataset[base + 2 + column_count*2 + 5] = ERL_DRV_ATOM;
dataset[base + 2 + column_count*2 + 5] = driver_mk_atom("rows"); dataset[base + 2 + column_count*2 + 6] = driver_mk_atom("rows");
} }
for (i = 0; i < column_count; i++) { for (i = 0; i < column_count; i++) {
@@ -173,7 +178,7 @@ static int sql_exec(sqlite3_drv_t *drv, char *command, int command_size) {
term_count += 4; term_count += 4;
dataset = realloc(dataset, sizeof(*dataset) * term_count); dataset = realloc(dataset, sizeof(*dataset) * term_count);
dataset[term_count - 4] = ERL_DRV_BINARY; dataset[term_count - 4] = ERL_DRV_BINARY;
dataset[term_count - 3] = binaries[binaries_count - 1]; dataset[term_count - 3] = (ErlDrvTermData)binaries[binaries_count - 1];
dataset[term_count - 2] = bytes; dataset[term_count - 2] = bytes;
dataset[term_count - 1] = 0; dataset[term_count - 1] = 0;
break; break;
@@ -196,10 +201,11 @@ static int sql_exec(sqlite3_drv_t *drv, char *command, int command_size) {
return return_error(drv, "SQLite3 database is busy"); return return_error(drv, "SQLite3 database is busy");
} }
term_count += 2; term_count += 3;
dataset = realloc(dataset, sizeof(*dataset) * term_count); dataset = realloc(dataset, sizeof(*dataset) * term_count);
dataset[term_count - 3] = ERL_DRV_NIL;
dataset[term_count - 2] = ERL_DRV_LIST; dataset[term_count - 2] = ERL_DRV_LIST;
dataset[term_count - 1] = row_count; dataset[term_count - 1] = row_count + 1;
term_count += 2; term_count += 2;
dataset = realloc(dataset, sizeof(*dataset) * term_count); dataset = realloc(dataset, sizeof(*dataset) * term_count);
@@ -207,9 +213,15 @@ static int sql_exec(sqlite3_drv_t *drv, char *command, int command_size) {
dataset[term_count - 1] = 2; dataset[term_count - 1] = 2;
term_count += 3;
dataset = realloc(dataset, sizeof(*dataset) * term_count);
dataset[term_count - 3] = ERL_DRV_NIL;
dataset[term_count - 2] = ERL_DRV_LIST;
dataset[term_count - 1] = 3;
term_count += 2; term_count += 2;
dataset = realloc(dataset, sizeof(*dataset) * term_count); dataset = realloc(dataset, sizeof(*dataset) * term_count);
dataset[term_count - 2] = ERL_DRV_LIST; dataset[term_count - 2] = ERL_DRV_TUPLE;
dataset[term_count - 1] = 2; dataset[term_count - 1] = 2;

View File

@@ -360,15 +360,19 @@ handle_call({sql_exec, SQL}, _From, #state{port = Port} = State) ->
Reply = exec(Port, {sql_exec, SQL}), Reply = exec(Port, {sql_exec, SQL}),
{reply, Reply, State}; {reply, Reply, State};
handle_call(list_tables, _From, #state{port = Port} = State) -> handle_call(list_tables, _From, #state{port = Port} = State) ->
Reply = exec(Port, {sql_exec, "select * from sqlite_master where type='table';"}), Reply = exec(Port, {sql_exec, "select name from sqlite_master where type='table';"}),
{reply, Reply, State}; TableList = proplists:get_value(rows, Reply),
TableNames = [binary_to_atom(Name, utf8) || {Name} <- TableList],
{reply, TableNames, State};
handle_call({table_info, Tbl}, _From, #state{port = Port} = State) -> handle_call({table_info, Tbl}, _From, #state{port = Port} = State) ->
% make sure we only get table info. % make sure we only get table info.
% SQL Injection warning % SQL Injection warning
SQL = io_lib:format("select sql from sqlite3_master where tbl_name = '~p' and type='table';", [Tbl]), SQL = io_lib:format("select sql from sqlite_master where tbl_name = '~p' and type='table';", [Tbl]),
[{Info}] = exec(Port, {sql_exec, SQL}), Data = exec(Port, {sql_exec, SQL}),
Reply = parse_table_info(Info), TableSql = proplists:get_value(rows, Data),
{reply, Reply, State}; [{Info}] = TableSql,
ColumnList = parse_table_info(binary_to_list(Info)),
{reply, ColumnList, State};
handle_call({create_table, Tbl, Options}, _From, #state{port = Port} = State) -> handle_call({create_table, Tbl, Options}, _From, #state{port = Port} = State) ->
SQL = sqlite3_lib:create_table_sql(Tbl, Options), SQL = sqlite3_lib:create_table_sql(Tbl, Options),
Cmd = {sql_exec, SQL}, Cmd = {sql_exec, SQL},
@@ -459,17 +463,12 @@ wait_result(Port) ->
{Port, Reply} -> {Port, Reply} ->
io:format("Reply: ~p~n", [Reply]), io:format("Reply: ~p~n", [Reply]),
Reply; Reply;
% List = binary_to_term(Data),
% if is_list(List) ->
% lists:reverse(List);
% true -> List
% end;
{error, Reason} -> {error, Reason} ->
io:format("Error: ~p~n", [Reason]), io:format("Error: ~p~n", [Reason]),
{error, Reason}; {error, Reason};
_Else -> _Else ->
io:format("Else: ~p~n", [_Else]), io:format("Else: ~p~n", [_Else]),
ok _Else
end. end.
exec(Port, {sql_exec, Cmd}) -> exec(Port, {sql_exec, Cmd}) ->

View File

@@ -3,7 +3,7 @@
-record(user, {name, age, wage}). -record(user, {name, age, wage}).
main(_) -> test() ->
sqlite3:open(ct), sqlite3:open(ct),
sqlite3:create_table(ct, user, [{name, text}, {age, integer}, {wage, integer}]), sqlite3:create_table(ct, user, [{name, text}, {age, integer}, {wage, integer}]),
[user] = sqlite3:list_tables(ct), [user] = sqlite3:list_tables(ct),
@@ -17,3 +17,10 @@ main(_) ->
%sqlite3:delete_db(ct) %sqlite3:delete_db(ct)
sqlite3:close(ct). sqlite3:close(ct).
main(_) ->
try test() of
_ -> ok
catch
Class:Error ->
io:format("~p:~p:~p~n", [Class, Error, erlang:get_stacktrace()])
end.