now can read table list from DB
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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}) ->
|
||||||
|
|||||||
9
test.erl
9
test.erl
@@ -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.
|
||||||
Reference in New Issue
Block a user