From be08fe62f3f2abef343612def6fcfc07ee64faf0 Mon Sep 17 00:00:00 2001 From: Max Lapshin Date: Wed, 14 Oct 2009 01:00:08 +0400 Subject: [PATCH] now can read table list from DB --- priv/sqlite3_drv.c | 38 +++++++++++++++++++++++++------------- src/sqlite3.erl | 23 +++++++++++------------ test.erl | 9 ++++++++- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/priv/sqlite3_drv.c b/priv/sqlite3_drv.c index 03fb1d9..47b417a 100644 --- a/priv/sqlite3_drv.c +++ b/priv/sqlite3_drv.c @@ -107,7 +107,7 @@ static int sql_exec(sqlite3_drv_t *drv, char *command, int command_size) { 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); 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); 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) { if (row_count == 0) { 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[base] = ERL_DRV_ATOM; dataset[base + 1] = driver_mk_atom("columns"); for (i = 0; i < column_count; i++) { 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 + column_count*2] = ERL_DRV_LIST; - dataset[base + 2 + column_count*2 + 1] = column_count; - dataset[base + 2 + column_count*2 + 2] = ERL_DRV_TUPLE; - dataset[base + 2 + column_count*2 + 3] = 2; + dataset[base + 2 + column_count*2 + 0] = ERL_DRV_NIL; + dataset[base + 2 + column_count*2 + 1] = ERL_DRV_LIST; + dataset[base + 2 + column_count*2 + 2] = column_count + 1; + 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] = driver_mk_atom("rows"); + dataset[base + 2 + column_count*2 + 5] = ERL_DRV_ATOM; + dataset[base + 2 + column_count*2 + 6] = driver_mk_atom("rows"); } 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; dataset = realloc(dataset, sizeof(*dataset) * term_count); 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 - 1] = 0; 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"); } - term_count += 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] = row_count; + dataset[term_count - 1] = row_count + 1; term_count += 2; 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; + 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; 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; diff --git a/src/sqlite3.erl b/src/sqlite3.erl index bdb828b..77d1b03 100644 --- a/src/sqlite3.erl +++ b/src/sqlite3.erl @@ -360,15 +360,19 @@ handle_call({sql_exec, SQL}, _From, #state{port = Port} = State) -> Reply = exec(Port, {sql_exec, SQL}), {reply, Reply, State}; handle_call(list_tables, _From, #state{port = Port} = State) -> - Reply = exec(Port, {sql_exec, "select * from sqlite_master where type='table';"}), - {reply, Reply, State}; + Reply = exec(Port, {sql_exec, "select name from sqlite_master where type='table';"}), + 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) -> % make sure we only get table info. % SQL Injection warning - SQL = io_lib:format("select sql from sqlite3_master where tbl_name = '~p' and type='table';", [Tbl]), - [{Info}] = exec(Port, {sql_exec, SQL}), - Reply = parse_table_info(Info), - {reply, Reply, State}; + SQL = io_lib:format("select sql from sqlite_master where tbl_name = '~p' and type='table';", [Tbl]), + Data = exec(Port, {sql_exec, SQL}), + TableSql = proplists:get_value(rows, Data), + [{Info}] = TableSql, + ColumnList = parse_table_info(binary_to_list(Info)), + {reply, ColumnList, State}; handle_call({create_table, Tbl, Options}, _From, #state{port = Port} = State) -> SQL = sqlite3_lib:create_table_sql(Tbl, Options), Cmd = {sql_exec, SQL}, @@ -459,17 +463,12 @@ wait_result(Port) -> {Port, Reply} -> io:format("Reply: ~p~n", [Reply]), Reply; - % List = binary_to_term(Data), - % if is_list(List) -> - % lists:reverse(List); - % true -> List - % end; {error, Reason} -> io:format("Error: ~p~n", [Reason]), {error, Reason}; _Else -> io:format("Else: ~p~n", [_Else]), - ok + _Else end. exec(Port, {sql_exec, Cmd}) -> diff --git a/test.erl b/test.erl index 8d4bd83..aa0871a 100755 --- a/test.erl +++ b/test.erl @@ -3,7 +3,7 @@ -record(user, {name, age, wage}). -main(_) -> +test() -> sqlite3:open(ct), sqlite3:create_table(ct, user, [{name, text}, {age, integer}, {wage, integer}]), [user] = sqlite3:list_tables(ct), @@ -17,3 +17,10 @@ main(_) -> %sqlite3:delete_db(ct) sqlite3:close(ct). +main(_) -> + try test() of + _ -> ok + catch + Class:Error -> + io:format("~p:~p:~p~n", [Class, Error, erlang:get_stacktrace()]) + end. \ No newline at end of file