From 89d9d0b17d65f3fc972ca449d85f59c4e070ca94 Mon Sep 17 00:00:00 2001 From: Max Lapshin Date: Tue, 13 Oct 2009 10:56:15 +0400 Subject: [PATCH] Trying to pass data into driver --- priv/Makefile | 2 +- priv/sqlite3_drv.c | 87 ++++++++++++++++------------------------------ priv/sqlite3_drv.h | 2 ++ src/sqlite3.erl | 13 +++++++ 4 files changed, 45 insertions(+), 59 deletions(-) diff --git a/priv/Makefile b/priv/Makefile index ec7fc65..899da77 100644 --- a/priv/Makefile +++ b/priv/Makefile @@ -1,5 +1,5 @@ GCC=gcc -LDFLAGS=-shared -lsqlite3 -bundle -flat_namespace -undefined suppress -fPIC +LDFLAGS=-shared -lsqlite3 -bundle -flat_namespace -undefined suppress -fPIC -lerl_interface -L/usr/local/lib/erlang/lib/erl_interface-3.6.1/lib -lei SRCS=sqlite3_drv.c sqlite3_drv.h OUTPUT=sqlite3_drv.so CFLAGS=-o ../ebin/${OUTPUT} -I/usr/local/lib/erlang/usr/include/ -I/usr/local/lib/erlang/lib/erl_interface-3.6.1/include/ -arch i386 -arch x86_64 diff --git a/priv/sqlite3_drv.c b/priv/sqlite3_drv.c index 8d76d18..770c3c1 100644 --- a/priv/sqlite3_drv.c +++ b/priv/sqlite3_drv.c @@ -63,23 +63,27 @@ static void stop(ErlDrvData handle) { 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[0]; // First byte is the command - fprintf(stderr, "Command: %s\n", data->orig_bytes); + int command = data->orig_bytes[1]; + fprintf(stderr, "Command: %d\n", command); + switch(command) { case CMD_LIST_TABLES: list_tables(driver_data, ev); break; - - // case CMD_GET: - // get(driver_data, ev); - // break; - // - // case CMD_DEL: - // del(driver_data, ev); - // break; - + + case CMD_SQL_EXEC: + sql_exec(driver_data, ev); + // + // // case CMD_GET: + // // get(driver_data, ev); + // // break; + // // + // // case CMD_DEL: + // // del(driver_data, ev); + // // break; + // default: unkown(driver_data, ev); } @@ -93,33 +97,16 @@ static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data) static void list_tables(sqlite3_drv_t *drv, ErlIOVec *ev) { } -#if 0 -// Insert or replace record in the database -static void put(sqlite3_drv_t *bdb_drv, ErlIOVec *ev) { - ErlDrvBinary* input = ev->binv[1]; - char *bytes = input->orig_bytes; - char *key_bytes = bytes+1; - char *value_bytes = bytes+1+KEY_SIZE; - int value_size = input->orig_size - 1 - KEY_SIZE; - - DB *db = bdb_drv->db; - DBT key; - DBT value; - int status; +static void sql_exec(sqlite3_drv_t *drv, ErlIOVec *ev) { - // Erase bytes to get rid of residual data - bzero(&key, sizeof(DBT)); - bzero(&value, sizeof(DBT)); - - key.data = key_bytes; - key.size = KEY_SIZE; - - value.data = value_bytes; - value.size = value_size; - - // Insert the record and then write it to disk - status = db->put(db, NULL, &key, &value, 0); - db->sync(db, 0); + ErlDrvBinary* input = ev->binv[1]; + char *command = input->orig_bytes + 1; + int command_size = input->orig_size - 1; + int status; + + fprintf(stderr, "Exec: %s\n", command); + + //int status = sqlite3_exec(drv->db, command if(status == 0) { // Insert went OK @@ -127,40 +114,24 @@ static void put(sqlite3_drv_t *bdb_drv, ErlIOVec *ev) { ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok")}; // Return the value to the Erlang VM - driver_output_term(bdb_drv->port, spec, sizeof(spec) / sizeof(spec[0])); + driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0])); } else { // There was an error return {error, Reason} char * error_reason; - switch(status) { - case DB_LOCK_DEADLOCK: - error_reason = "deadlock"; - break; - case EACCES: - error_reason = "readonly"; - break; - case EINVAL: - error_reason = "badflag"; - break; - case ENOSPC: - error_reason = "btree_max"; - break; - case DB_RUNRECOVERY: - error_reason = "run_recovery"; - break; - default: - error_reason = "unkown"; - } + error_reason = "unkown"; // Returns tuple {error, Reason} ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_ATOM, driver_mk_atom(error_reason), ERL_DRV_TUPLE, 2}; - driver_output_term(bdb_drv->port, spec, sizeof(spec) / sizeof(spec[0])); + driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0])); } } +#if 0 + // Retrieve a record from the database, if it exists static void get(sqlite3_drv_t *bdb_drv, ErlIOVec *ev) { ErlDrvBinary* input = ev->binv[1]; diff --git a/priv/sqlite3_drv.h b/priv/sqlite3_drv.h index 4be71a4..6a97d28 100644 --- a/priv/sqlite3_drv.h +++ b/priv/sqlite3_drv.h @@ -3,6 +3,7 @@ #include #include #include +#include // Path to file where data will be stored. // It will be created if it doesn't exist @@ -30,6 +31,7 @@ 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); static void unkown(sqlite3_drv_t *bdb_drv, ErlIOVec *ev); diff --git a/src/sqlite3.erl b/src/sqlite3.erl index c41baaf..05e248f 100644 --- a/src/sqlite3.erl +++ b/src/sqlite3.erl @@ -452,6 +452,19 @@ code_change(_OldVsn, State, _Extra) -> 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) -> + 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