Add update operation

This commit is contained in:
sergey-miryanov
2010-01-20 14:13:27 +05:00
parent ebe060caf8
commit 2583ec83ee
2 changed files with 106 additions and 1 deletions

View File

@@ -19,6 +19,7 @@
-export([create_table/2, create_table/3]). -export([create_table/2, create_table/3]).
-export([list_tables/0, list_tables/1, table_info/1, table_info/2]). -export([list_tables/0, list_tables/1, table_info/1, table_info/2]).
-export([write/2, write/3]). -export([write/2, write/3]).
-export([update/4, update/5]).
-export([read/2, read/3]). -export([read/2, read/3]).
-export([delete/2, delete/3]). -export([delete/2, delete/3]).
-export([drop_table/1, drop_table/2]). -export([drop_table/1, drop_table/2]).
@@ -240,6 +241,36 @@ write(Tbl, Data) ->
write(Db, Tbl, Data) -> write(Db, Tbl, Data) ->
gen_server:call(Db, {write, Tbl, Data}). gen_server:call(Db, {write, Tbl, Data}).
%%--------------------------------------------------------------------
%% @spec update (Tbl::atom (), Key::atom (), Value, Data) -> Result
%% Value = any ()
%% Data = [{Column::atom (), Value::string () | integer () | float ()}]
%% Result = {ok, ID} | Unknown
%% Unknown = term ()
%% @doc
%% Updates rows into Tbl table such that the Value matches the
%% value in Key with Data. Returns ID of the first updated
%% record.
%% @end
%%--------------------------------------------------------------------
update (Tbl, Key, Value, Data) ->
?MODULE:update (?MODULE, Tbl, Key, Value, Data).
%%--------------------------------------------------------------------
%% @spec update (Db::atom (), Tbl::atom (), Key::atom (), Value, Data) -> Result
%% Value = any ()
%% Data = [{Column::atom (), Value::string () | integer () | float ()}]
%% Result = {ok, ID} | Unknown
%% Unknown = term ()
%% @doc
%% Updates rows into Tbl table in Db dbase such that the Value
%% matches the value in Key with Data. Returns ID of the first
%% updated record.
%% @end
%%--------------------------------------------------------------------
update (Db, Tbl, Key, Value, Data) ->
gen_server:call (Db, {update, Tbl, Key, Value, Data}).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @spec read(Tbl::atom(), Key) -> [term()] %% @spec read(Tbl::atom(), Key) -> [term()]
%% Key = {ColName::atom(), ColValue::term()} %% Key = {ColName::atom(), ColValue::term()}
@@ -397,6 +428,9 @@ 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 ({update, Tbl, Key, Value, Data}, _From, #state{port = Port} = State)->
Reply = exec (Port, {sql_exec, sqlite3_lib:update_sql (Tbl, Key, Value, Data)}),
{reply, Reply, State};
handle_call({write, Tbl, Data}, _From, #state{port = Port} = State) -> handle_call({write, Tbl, Data}, _From, #state{port = Port} = State) ->
% insert into t1 (data,num) values ('This is sample data',3); % insert into t1 (data,num) values ('This is sample data',3);
Reply = exec(Port, {sql_exec, sqlite3_lib:write_sql(Tbl, Data)}), Reply = exec(Port, {sql_exec, sqlite3_lib:write_sql(Tbl, Data)}),

View File

@@ -12,6 +12,7 @@
-export([col_type/1]). -export([col_type/1]).
-export([write_value_sql/1, write_col_sql/1]). -export([write_value_sql/1, write_col_sql/1]).
-export([create_table_sql/2, write_sql/2, read_sql/3, delete_sql/3, drop_table/1]). -export([create_table_sql/2, write_sql/2, read_sql/3, delete_sql/3, drop_table/1]).
-export ([update_sql/4, update_set_sql/1, replace/1]).
%%==================================================================== %%====================================================================
%% API %% API
@@ -19,6 +20,7 @@
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @spec col_type(Type :: term()) -> term() %% @spec col_type(Type :: term()) -> term()
%% @doc Maps sqlite3 column type. %% @doc Maps sqlite3 column type.
%% @end
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
-spec(col_type/1::(atom() | string()) -> atom() | string()). -spec(col_type/1::(atom() | string()) -> atom() | string()).
col_type(integer) -> col_type(integer) ->
@@ -59,6 +61,7 @@ write_value_sql(Values) ->
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @spec write_col_sql([atom()]) -> string() %% @spec write_col_sql([atom()]) -> string()
%% @doc Creates the column/data stmt for SQL. %% @doc Creates the column/data stmt for SQL.
%% @end
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
-spec(write_col_sql/1::([atom()]) -> string()). -spec(write_col_sql/1::([atom()]) -> string()).
write_col_sql(Cols) -> write_col_sql(Cols) ->
@@ -67,12 +70,58 @@ write_col_sql(Cols) ->
end, Cols), end, Cols),
string:join(StrCols, ","). string:join(StrCols, ",").
%%--------------------------------------------------------------------
%% @spec replace (String) -> string ()
%% String = string ()
%% @doc Returns copy of String for which \" replaced with '
%% @end
%%--------------------------------------------------------------------
-spec (replace/1::(string ()) -> string ()).
replace ([34 | T]) ->
replace (T, ["'"]);
replace ([H | T]) ->
replace (T, [binary_to_list (<<H>>)]).
replace ([], L) ->
lists:flatten (lists:reverse (L));
replace ([34 | T], L) ->
replace (T, ["'" | L]);
replace ([H | T], L) ->
replace (T, [binary_to_list (<<H>>) | L]).
%%--------------------------------------------------------------------
%% @spec update_set_sql ([{Col, Value}]) -> string ()
%% Col = atom ()
%% Value = integer () | float () | string ()
%% @doc
%% Creates update set stmt.
%% Currently only supports integer, double/float and strings.
%% For strings \" replaced with '.
%% @end
%%--------------------------------------------------------------------
-spec (update_set_sql/1::(any ()) -> string ()).
update_set_sql (Data) ->
Set = lists:map (fun
({Col, Value}) when is_integer (Value) ->
string:join (
[atom_to_list (Col), integer_to_list (Value)], " = ");
({Col, Value}) when is_float (Value) ->
string:join (
[atom_to_list (Col), integer_to_list (Value)], " = ");
({Col, Value}) ->
string:join (
[atom_to_list (Col),
io_lib:format ("\"~s\"", [replace (Value)])], " = ")
end,
Data),
string:join (Set, ", ").
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @spec create_table_sql(Tbl, [{ColName, Type}]) -> string() %% @spec create_table_sql(Tbl, [{ColName, Type}]) -> string()
%% Tbl = atom() %% Tbl = atom()
%% ColName = atom() %% ColName = atom()
%% Type = string() %% Type = string()
%% @doc Generates a table create stmt in SQL. %% @doc Generates a table create stmt in SQL.
%% @end
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
-spec(create_table_sql/2::(atom(), [{atom(), string()}]) -> string()). -spec(create_table_sql/2::(atom(), [{atom(), string()}]) -> string()).
create_table_sql(Tbl, [{ColName, Type} | Tl]) -> create_table_sql(Tbl, [{ColName, Type} | Tl]) ->
@@ -84,6 +133,29 @@ create_table_sql(Tbl, [{ColName, Type} | Tl]) ->
end, Tl), ", ") ++ ");", end, Tl), ", ") ++ ");",
lists:flatten(CT ++ Start ++ End). lists:flatten(CT ++ Start ++ End).
%%--------------------------------------------------------------------
%% @spec update_sql (Tbl, Key, Value, Data) -> string ()
%% Tbl = atom ()
%% Key = atom ()
%% Value = atom ()
%% Data = [{ColName :: atom (), Value :: string () | integer () | float ()}]
%% @doc
%% Using Key as the column name and Data as list of column names
%% and values pairs it creates the proper update SQL stmt for the
%% record with matching Value.
%% @end
%%--------------------------------------------------------------------
-type(sql_value() :: string() | integer() | float()).
-spec (update_sql/4::(atom (), atom (), atom (), [{atom (), sql_value ()}]) -> string ()).
update_sql (Tbl, Key, Value, Data) ->
lists:flatten (
io_lib:format ("UPDATE ~p SET ~s WHERE ~p = ~p;",
[Tbl,
sqlite3_lib:update_set_sql (Data),
Key,
Value
])).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @spec write_sql(Tbl, Data) -> string() %% @spec write_sql(Tbl, Data) -> string()
%% Tbl = atom() %% Tbl = atom()
@@ -92,7 +164,6 @@ create_table_sql(Tbl, [{ColName, Type} | Tl]) ->
%% proper insertion SQL stmt. %% proper insertion SQL stmt.
%% @end %% @end
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
-type(sql_value() :: string() | integer() | float()).
-spec(write_sql/2::(atom(), [{atom(), sql_value()}]) -> string()). -spec(write_sql/2::(atom(), [{atom(), sql_value()}]) -> string()).
write_sql(Tbl, Data) -> write_sql(Tbl, Data) ->
{Cols, Values} = lists:unzip(Data), {Cols, Values} = lists:unzip(Data),