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;
|
sqlite3_drv_t* driver_data = (sqlite3_drv_t*) handle;
|
||||||
ErlDrvBinary* data = ev->binv[1];
|
ErlDrvBinary* data = ev->binv[1];
|
||||||
|
|
||||||
int command = data->orig_bytes[1];
|
int command = data->orig_bytes[0];
|
||||||
fprintf(stderr, "Command: %d\n", command);
|
|
||||||
|
|
||||||
|
|
||||||
switch(command) {
|
switch(command) {
|
||||||
case CMD_LIST_TABLES:
|
|
||||||
list_tables(driver_data, ev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CMD_SQL_EXEC:
|
case CMD_SQL_EXEC:
|
||||||
sql_exec(driver_data, ev);
|
sql_exec(driver_data, ev);
|
||||||
|
break;
|
||||||
//
|
//
|
||||||
// // case CMD_GET:
|
// // case CMD_GET:
|
||||||
// // get(driver_data, ev);
|
// // get(driver_data, ev);
|
||||||
@@ -94,8 +90,34 @@ 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) {
|
static void sql_exec(sqlite3_drv_t *drv, ErlIOVec *ev) {
|
||||||
|
|
||||||
@@ -103,31 +125,22 @@ static void sql_exec(sqlite3_drv_t *drv, ErlIOVec *ev) {
|
|||||||
char *command = input->orig_bytes + 1;
|
char *command = input->orig_bytes + 1;
|
||||||
int command_size = input->orig_size - 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) {
|
if(status != SQLITE_OK) {
|
||||||
// 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}
|
|
||||||
ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"),
|
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};
|
ERL_DRV_TUPLE, 2};
|
||||||
|
|
||||||
driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0]));
|
driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0]));
|
||||||
}
|
}
|
||||||
|
if (error) {
|
||||||
|
sqlite3_free(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#define DB_PATH "./store.db"
|
#define DB_PATH "./store.db"
|
||||||
|
|
||||||
// Binary commands between Erlang VM and Driver
|
// Binary commands between Erlang VM and Driver
|
||||||
#define CMD_LIST_TABLES 1
|
|
||||||
#define CMD_SQL_EXEC 2
|
#define CMD_SQL_EXEC 2
|
||||||
// #define CMD_DEL 3
|
// #define CMD_DEL 3
|
||||||
|
|
||||||
@@ -30,7 +29,6 @@ static ErlDrvData start(ErlDrvPort port, char* cmd);
|
|||||||
static void stop(ErlDrvData handle);
|
static void stop(ErlDrvData handle);
|
||||||
static void outputv(ErlDrvData handle, ErlIOVec *ev);
|
static void outputv(ErlDrvData handle, ErlIOVec *ev);
|
||||||
static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data);
|
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 sql_exec(sqlite3_drv_t *drv, ErlIOVec *ev);
|
||||||
// static void get(bdb_drv_t *bdb_drv, ErlIOVec *ev);
|
// static void get(bdb_drv_t *bdb_drv, ErlIOVec *ev);
|
||||||
// static void del(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;
|
ETERM **record_list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (result == 0) {
|
|
||||||
result = erl_mk_empty_list();
|
|
||||||
}
|
|
||||||
|
|
||||||
record_list = malloc(argc * sizeof(ETERM *));
|
record_list = malloc(argc * sizeof(ETERM *));
|
||||||
|
|
||||||
fprintf(log, "runs %d\n", argc);
|
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 = 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, {list_tables, none}),
|
Reply = exec(Port, {sql_exec, "select * from sqlite_master where type='table';"}),
|
||||||
{reply, Reply, State};
|
{reply, Reply, 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.
|
||||||
@@ -449,24 +449,12 @@ code_change(_OldVsn, State, _Extra) ->
|
|||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-define(SQL_EXEC_COMMAND, 2).
|
||||||
|
|
||||||
create_cmd(Dbase) ->
|
create_cmd(Dbase) ->
|
||||||
"sqlite3_port " ++ Dbase.
|
"sqlite3_port " ++ Dbase.
|
||||||
|
|
||||||
exec(Port, {sql_exec, Cmd}) ->
|
wait_result(Port) ->
|
||||||
port_command(Port, <<2, (list_to_binary(Cmd))/binary>>),
|
|
||||||
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;
|
|
||||||
|
|
||||||
exec(Port, Cmd) ->
|
|
||||||
port_command(Port, term_to_binary(Cmd)),
|
|
||||||
receive
|
receive
|
||||||
{Port, {data, Data}} when is_binary(Data) ->
|
{Port, {data, Data}} when is_binary(Data) ->
|
||||||
List = binary_to_term(Data),
|
List = binary_to_term(Data),
|
||||||
@@ -478,6 +466,10 @@ exec(Port, Cmd) ->
|
|||||||
ok
|
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) ->
|
parse_table_info(Info) ->
|
||||||
[_, Tail] = string:tokens(Info, "()"),
|
[_, Tail] = string:tokens(Info, "()"),
|
||||||
|
|||||||
Reference in New Issue
Block a user