Makefile changes for better compiles.

sqlite.erl supports start_link/stop and open/close paradigm.
added write_sql creation.
This commit is contained in:
Tee Teoh
2008-06-18 23:34:09 -04:00
parent 1f42c1fe39
commit e4878b2064
2 changed files with 70 additions and 17 deletions

View File

@@ -4,8 +4,8 @@ FLAGS=-I$(OTP_DIR)/include -L$(OTP_DIR)/lib
#GCC=/opt/local/bin/gcc-apple-4.2 #GCC=/opt/local/bin/gcc-apple-4.2
GCC=/usr/bin/gcc GCC=/usr/bin/gcc
all: erl_comm.c sqlite_port.c all: obj
$(GCC) -Wall -o sqlite_port erl_comm.c sqlite_port.c $(FLAGS) $(LIB) $(GCC) -Wall -o sqlite_port $(FLAGS) $(LIB) erl_comm.o sqlite_port.o
obj: erl_comm.c sqlite_port.c obj: erl_comm.c sqlite_port.c
$(GCC) -Wall -c $(FLAGS) erl_comm.c sqlite_port.c $(GCC) -Wall -c $(FLAGS) erl_comm.c sqlite_port.c

View File

@@ -12,12 +12,14 @@
%% API %% API
-export([open/1, open/2]). -export([open/1, open/2]).
-export([start_link/1, start_link/2]). -export([start_link/1, start_link/2]).
-export([stop/1, close/1]). -export([stop/0, close/1]).
-export([sql_exec/2]). -export([sql_exec/1, sql_exec/2]).
-export([create_table/3]). -export([create_table/2, create_table/3]).
-export([list_tables/1, table_info/2]). -export([list_tables/0, list_tables/1, table_info/1, table_info/2]).
-export([create_table_sql/2]). -export([write/2, write/3]).
-export([write_sql/2, write_col_sql/1, write_value_sql/1]).
%% gen_server callbacks %% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -33,7 +35,7 @@
%% Description: Starts the server %% Description: Starts the server
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
start_link(Db) -> start_link(Db) ->
start_link(Db, [{db, "./" ++ atom_to_list(Db) ++ ".db"}]). ?MODULE:open(?MODULE, [{db, "./" ++ atom_to_list(Db) ++ ".db"}]).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Function: start_link(Db, Options) -> {ok,Pid} | ignore | {error,Error} %% Function: start_link(Db, Options) -> {ok,Pid} | ignore | {error,Error}
@@ -41,33 +43,56 @@ start_link(Db) ->
%% {db, DbFile :: String()} %% {db, DbFile :: String()}
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
start_link(Db, Options) -> start_link(Db, Options) ->
gen_server:start_link({local, Db}, ?MODULE, Options, []). Opts = case proplists:get_value(db, Options) of
undefined -> [{db, "./" ++ atom_to_list(Db) ++ ".db"} | Options];
_ -> Options
end,
?MODULE:open(?MODULE, Opts).
open(Db) -> open(Db) ->
?MODULE:start_link(Db). ?MODULE:open(Db, [{db, "./" ++ atom_to_list(Db) ++ ".db"}]).
open(Db, Options) -> open(Db, Options) ->
?MODULE:start_link(Db, Options). gen_server:start_link({local, Db}, ?MODULE, Options, []).
close(Db) -> close(Db) ->
gen_server:call(Db, close). gen_server:call(Db, close).
stop(Db) -> stop() ->
?MODULE:close(Db). ?MODULE:close(?MODULE).
sql_exec(SQL) ->
?MODULE:sql_exec(?MODULE, SQL).
sql_exec(Db, SQL) -> sql_exec(Db, SQL) ->
gen_server:call(Db, {sql_exec, SQL}). gen_server:call(Db, {sql_exec, SQL}).
create_table(Tbl, Options) ->
?MODULE:create_table(?MODULE, Tbl, Options).
create_table(Db, Tbl, Options) -> create_table(Db, Tbl, Options) ->
gen_server:call(Db, {create_table, Tbl, Options}). gen_server:call(Db, {create_table, Tbl, Options}).
% returns list or ok % returns list or ok
list_tables() ->
?MODULE:list_tables(?MODULE).
list_tables(Db) -> list_tables(Db) ->
gen_server:call(Db, list_tables). gen_server:call(Db, list_tables).
table_info(Tbl) ->
?MODULE:table_info(?MODULE, Tbl).
table_info(Db, Tbl) -> table_info(Db, Tbl) ->
gen_server:call(Db, {table_info, Tbl}). gen_server:call(Db, {table_info, Tbl}).
write(Tbl, Data) ->
?MODULE:write(?MODULE, Tbl, Data).
write(Db, Tbl, Data) ->
gen_server:call(Db, {write, Tbl, Data}).
%%==================================================================== %%====================================================================
%% gen_server callbacks %% gen_server callbacks
%%==================================================================== %%====================================================================
@@ -103,10 +128,10 @@ handle_call(list_tables, _From, #state{port = Port} = State) ->
Reply = exec(Port, {list_tables, none}), Reply = exec(Port, {list_tables, none}),
{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.
% SQL Injection warning
SQL = io_lib:format("select sql from sqlite_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]),
Cmd = {sql_exec, SQL}, [{Info}] = exec(Port, {sql_exec, SQL}),
[{Info}] = exec(Port, Cmd),
Reply = parse_table_info(Info), Reply = parse_table_info(Info),
{reply, Reply, State}; {reply, Reply, State};
handle_call({create_table, Tbl, Options}, _From, #state{port = Port} = State) -> handle_call({create_table, Tbl, Options}, _From, #state{port = Port} = State) ->
@@ -114,6 +139,10 @@ handle_call({create_table, Tbl, Options}, _From, #state{port = Port} = State) ->
Cmd = {sql_exec, SQL}, Cmd = {sql_exec, SQL},
Reply = exec(Port, Cmd), Reply = exec(Port, Cmd),
{reply, Reply, State}; {reply, Reply, State};
handle_call({write, Tbl, Data}, _From, #state{port = Port} = State) ->
% insert into t1 (data,num) values ('This is sample data',3);
Reply = ok,
{reply, Reply, State};
handle_call(_Request, _From, State) -> handle_call(_Request, _From, State) ->
Reply = ok, Reply = ok,
{reply, Reply, State}. {reply, Reply, State}.
@@ -201,6 +230,30 @@ create_table_sql(Tbl, [{Name, Type} | Tl]) ->
end, Tl), ", ") ++ ");", end, Tl), ", ") ++ ");",
lists:flatten(CT ++ Start ++ End). lists:flatten(CT ++ Start ++ End).
% insert into t1 (data,num) values ('This is sample data',3);
write_sql(Tbl, Data) ->
{Cols, Values} = lists:unzip(Data),
lists:flatten(io_lib:format("INSERT INTO ~p (~s) values (~s);",
[Tbl, write_col_sql(Cols), write_value_sql(Values)])).
% currently only support integer, double/float and strings
write_value_sql(Values) ->
StrValues = lists:map(fun(X) when is_integer(X) ->
integer_to_list(X);
(X) when is_float(X) ->
float_to_list(X);
(X) ->
io_lib:format("'~s'", [X])
end, Values),
string:join(StrValues, ",").
write_col_sql(Cols) ->
StrCols = lists:map(fun(X) ->
atom_to_list(X)
end, Cols),
string:join(StrCols, ",").
col_type("INTEGER") -> col_type("INTEGER") ->
integer; integer;
col_type("TEXT") -> col_type("TEXT") ->