can pass sql into driver
This commit is contained in:
@@ -64,17 +64,13 @@ static void outputv(ErlDrvData handle, ErlIOVec *ev) {
|
||||
sqlite3_drv_t* driver_data = (sqlite3_drv_t*) handle;
|
||||
ErlDrvBinary* data = ev->binv[1];
|
||||
|
||||
int command = data->orig_bytes[1];
|
||||
fprintf(stderr, "Command: %d\n", command);
|
||||
int command = data->orig_bytes[0];
|
||||
|
||||
|
||||
switch(command) {
|
||||
case CMD_LIST_TABLES:
|
||||
list_tables(driver_data, ev);
|
||||
break;
|
||||
|
||||
case CMD_SQL_EXEC:
|
||||
sql_exec(driver_data, ev);
|
||||
break;
|
||||
//
|
||||
// // case CMD_GET:
|
||||
// // get(driver_data, ev);
|
||||
@@ -94,40 +90,57 @@ static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data)
|
||||
|
||||
}
|
||||
|
||||
static void list_tables(sqlite3_drv_t *drv, ErlIOVec *ev) {
|
||||
static int callback(void *data, int argc, char **argv, char **azColName)
|
||||
{
|
||||
sqlite3_drv_t *drv = (sqlite3_drv_t *)data;
|
||||
int i;
|
||||
|
||||
// ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"),
|
||||
// ERL_DRV_STRING, error_reason, strlen(error_reason),
|
||||
// ERL_DRV_TUPLE, 2};
|
||||
//
|
||||
// driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0]));
|
||||
|
||||
|
||||
|
||||
// record_list = malloc(argc * sizeof(ETERM *));
|
||||
|
||||
fprintf(stderr, "runs %d\n", argc);
|
||||
for (i = 0; i < argc; i++) {
|
||||
fprintf(stderr, "%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
|
||||
// result = erl_cons(erl_mk_tuple(record_list, argc), result);
|
||||
|
||||
// free(record_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void sql_exec(sqlite3_drv_t *drv, ErlIOVec *ev) {
|
||||
|
||||
ErlDrvBinary* input = ev->binv[1];
|
||||
char *command = input->orig_bytes + 1;
|
||||
int command_size = input->orig_size - 1;
|
||||
int status;
|
||||
int status;
|
||||
char *error = NULL;
|
||||
|
||||
fprintf(stderr, "Exec: %s\n", command);
|
||||
fprintf(stderr, "Exec: %*s\n", command_size, command);
|
||||
|
||||
//int status = sqlite3_exec(drv->db, command
|
||||
status = sqlite3_exec(drv->db, command, callback, drv, &error);
|
||||
|
||||
if(status == 0) {
|
||||
// Insert went OK
|
||||
// Prepare return value to Erlang VM, returns atom 'ok'
|
||||
ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok")};
|
||||
|
||||
// Return the value to the Erlang VM
|
||||
driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0]));
|
||||
} else {
|
||||
// There was an error return {error, Reason}
|
||||
char * error_reason;
|
||||
|
||||
error_reason = "unkown";
|
||||
|
||||
// Returns tuple {error, Reason}
|
||||
if(status != SQLITE_OK) {
|
||||
ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"),
|
||||
ERL_DRV_ATOM, driver_mk_atom(error_reason),
|
||||
ERL_DRV_STRING, error, strlen(error),
|
||||
ERL_DRV_TUPLE, 2};
|
||||
|
||||
driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0]));
|
||||
}
|
||||
if (error) {
|
||||
sqlite3_free(error);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#define DB_PATH "./store.db"
|
||||
|
||||
// Binary commands between Erlang VM and Driver
|
||||
#define CMD_LIST_TABLES 1
|
||||
#define CMD_SQL_EXEC 2
|
||||
// #define CMD_DEL 3
|
||||
|
||||
@@ -30,7 +29,6 @@ static ErlDrvData start(ErlDrvPort port, char* cmd);
|
||||
static void stop(ErlDrvData handle);
|
||||
static void outputv(ErlDrvData handle, ErlIOVec *ev);
|
||||
static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data);
|
||||
static void list_tables(sqlite3_drv_t *drv, ErlIOVec *ev);
|
||||
static void sql_exec(sqlite3_drv_t *drv, ErlIOVec *ev);
|
||||
// static void get(bdb_drv_t *bdb_drv, ErlIOVec *ev);
|
||||
// static void del(bdb_drv_t *bdb_drv, ErlIOVec *ev);
|
||||
|
||||
@@ -39,10 +39,6 @@ static int callback(void *notUsed, int argc, char **argv, char **azColName)
|
||||
ETERM **record_list;
|
||||
int i;
|
||||
|
||||
if (result == 0) {
|
||||
result = erl_mk_empty_list();
|
||||
}
|
||||
|
||||
record_list = malloc(argc * sizeof(ETERM *));
|
||||
|
||||
fprintf(log, "runs %d\n", argc);
|
||||
|
||||
@@ -360,7 +360,7 @@ 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, {list_tables, none}),
|
||||
Reply = exec(Port, {sql_exec, "select * from sqlite_master where type='table';"}),
|
||||
{reply, Reply, State};
|
||||
handle_call({table_info, Tbl}, _From, #state{port = Port} = State) ->
|
||||
% make sure we only get table info.
|
||||
@@ -449,13 +449,14 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-define(SQL_EXEC_COMMAND, 2).
|
||||
|
||||
create_cmd(Dbase) ->
|
||||
"sqlite3_port " ++ Dbase.
|
||||
|
||||
exec(Port, {sql_exec, Cmd}) ->
|
||||
port_command(Port, <<2, (list_to_binary(Cmd))/binary>>),
|
||||
receive
|
||||
{Port, {data, Data}} when is_binary(Data) ->
|
||||
wait_result(Port) ->
|
||||
receive
|
||||
{Port, {data, Data}} when is_binary(Data) ->
|
||||
List = binary_to_term(Data),
|
||||
if is_list(List) ->
|
||||
lists:reverse(List);
|
||||
@@ -463,21 +464,12 @@ exec(Port, {sql_exec, Cmd}) ->
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
|
||||
exec(Port, Cmd) ->
|
||||
port_command(Port, term_to_binary(Cmd)),
|
||||
receive
|
||||
{Port, {data, Data}} when is_binary(Data) ->
|
||||
List = binary_to_term(Data),
|
||||
if is_list(List) ->
|
||||
lists:reverse(List);
|
||||
true -> List
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
end.
|
||||
|
||||
exec(Port, {sql_exec, Cmd}) ->
|
||||
port_command(Port, <<?SQL_EXEC_COMMAND, (list_to_binary(Cmd))/binary>>),
|
||||
wait_result(Port).
|
||||
|
||||
|
||||
parse_table_info(Info) ->
|
||||
[_, Tail] = string:tokens(Info, "()"),
|
||||
|
||||
Reference in New Issue
Block a user