Indentation fixed
This commit is contained in:
@@ -552,7 +552,7 @@ handle_call(close, _From, State) ->
|
|||||||
Reply = ok,
|
Reply = ok,
|
||||||
{stop, normal, Reply, State};
|
{stop, normal, Reply, State};
|
||||||
handle_call(list_tables, _From, State) ->
|
handle_call(list_tables, _From, State) ->
|
||||||
SQL = "select name from sqlite_master where type='table';",
|
SQL = "select name from sqlite_master where type='table';",
|
||||||
Data = do_sql_exec(SQL, State),
|
Data = do_sql_exec(SQL, State),
|
||||||
TableList = proplists:get_value(rows, Data),
|
TableList = proplists:get_value(rows, Data),
|
||||||
TableNames = [erlang:list_to_atom(erlang:binary_to_list(Name)) || {Name} <- TableList],
|
TableNames = [erlang:list_to_atom(erlang:binary_to_list(Name)) || {Name} <- TableList],
|
||||||
@@ -576,45 +576,45 @@ handle_call({create_function, FunctionName, Function}, _From, #state{port = Port
|
|||||||
Reply = exec(Port, {create_function, FunctionName, Function}),
|
Reply = exec(Port, {create_function, FunctionName, Function}),
|
||||||
{reply, Reply, State};
|
{reply, Reply, State};
|
||||||
handle_call({sql_exec, SQL}, _From, State) ->
|
handle_call({sql_exec, SQL}, _From, State) ->
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({create_table, Tbl, Columns}, _From, State) ->
|
handle_call({create_table, Tbl, Columns}, _From, State) ->
|
||||||
SQL = sqlite3_lib:create_table_sql(Tbl, Columns),
|
SQL = sqlite3_lib:create_table_sql(Tbl, Columns),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({create_table, Tbl, Columns, Constraints}, _From, State) ->
|
handle_call({create_table, Tbl, Columns, Constraints}, _From, State) ->
|
||||||
SQL = sqlite3_lib:create_table_sql(Tbl, Columns, Constraints),
|
SQL = sqlite3_lib:create_table_sql(Tbl, Columns, Constraints),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({update, Tbl, Key, Value, Data}, _From, State) ->
|
handle_call({update, Tbl, Key, Value, Data}, _From, State) ->
|
||||||
SQL = sqlite3_lib:update_sql(Tbl, Key, Value, Data),
|
SQL = sqlite3_lib:update_sql(Tbl, Key, Value, Data),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({write, Tbl, Data}, _From, State) ->
|
handle_call({write, Tbl, Data}, _From, State) ->
|
||||||
% insert into t1 (data,num) values ('This is sample data',3);
|
% insert into t1 (data,num) values ('This is sample data',3);
|
||||||
SQL = sqlite3_lib:write_sql(Tbl, Data),
|
SQL = sqlite3_lib:write_sql(Tbl, Data),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({write_many, Tbl, DataList}, _From, State) ->
|
handle_call({write_many, Tbl, DataList}, _From, State) ->
|
||||||
do_sql_exec("BEGIN;", State),
|
do_sql_exec("BEGIN;", State),
|
||||||
[do_sql_exec(sqlite3_lib:write_sql(Tbl, Data), State) || Data <- DataList],
|
[do_sql_exec(sqlite3_lib:write_sql(Tbl, Data), State) || Data <- DataList],
|
||||||
do_handle_call_sql_exec("COMMIT;", State);
|
do_handle_call_sql_exec("COMMIT;", State);
|
||||||
handle_call({read, Tbl}, _From, State) ->
|
handle_call({read, Tbl}, _From, State) ->
|
||||||
% select * from Tbl where Key = Value;
|
% select * from Tbl where Key = Value;
|
||||||
SQL = sqlite3_lib:read_sql(Tbl),
|
SQL = sqlite3_lib:read_sql(Tbl),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({read, Tbl, Columns}, _From, State) ->
|
handle_call({read, Tbl, Columns}, _From, State) ->
|
||||||
SQL = sqlite3_lib:read_sql(Tbl, Columns),
|
SQL = sqlite3_lib:read_sql(Tbl, Columns),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({read, Tbl, Key, Value}, _From, State) ->
|
handle_call({read, Tbl, Key, Value}, _From, State) ->
|
||||||
% select * from Tbl where Key = Value;
|
% select * from Tbl where Key = Value;
|
||||||
SQL = sqlite3_lib:read_sql(Tbl, Key, Value),
|
SQL = sqlite3_lib:read_sql(Tbl, Key, Value),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({read, Tbl, Key, Value, Columns}, _From, State) ->
|
handle_call({read, Tbl, Key, Value, Columns}, _From, State) ->
|
||||||
SQL = sqlite3_lib:read_sql(Tbl, Key, Value, Columns),
|
SQL = sqlite3_lib:read_sql(Tbl, Key, Value, Columns),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({delete, Tbl, {Key, Value}}, _From, State) ->
|
handle_call({delete, Tbl, {Key, Value}}, _From, State) ->
|
||||||
% delete from Tbl where Key = Value;
|
% delete from Tbl where Key = Value;
|
||||||
SQL = sqlite3_lib:delete_sql(Tbl, Key, Value),
|
SQL = sqlite3_lib:delete_sql(Tbl, Key, Value),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call({drop_table, Tbl}, _From, State) ->
|
handle_call({drop_table, Tbl}, _From, State) ->
|
||||||
SQL = sqlite3_lib:drop_table_sql(Tbl),
|
SQL = sqlite3_lib:drop_table_sql(Tbl),
|
||||||
do_handle_call_sql_exec(SQL, State);
|
do_handle_call_sql_exec(SQL, State);
|
||||||
handle_call(_Request, _From, State) ->
|
handle_call(_Request, _From, State) ->
|
||||||
Reply = ok,
|
Reply = ok,
|
||||||
{reply, Reply, State}.
|
{reply, Reply, State}.
|
||||||
@@ -684,8 +684,8 @@ create_port_cmd(Dbase) ->
|
|||||||
atom_to_list(?DRIVER_NAME) ++ " " ++ Dbase.
|
atom_to_list(?DRIVER_NAME) ++ " " ++ Dbase.
|
||||||
|
|
||||||
do_handle_call_sql_exec(SQL, State) ->
|
do_handle_call_sql_exec(SQL, State) ->
|
||||||
Reply = do_sql_exec(SQL, State),
|
Reply = do_sql_exec(SQL, State),
|
||||||
{reply, Reply, State}.
|
{reply, Reply, State}.
|
||||||
|
|
||||||
do_sql_exec(SQL, #state{port = Port}) ->
|
do_sql_exec(SQL, #state{port = Port}) ->
|
||||||
?dbg("SQL: ~s~n", [SQL]),
|
?dbg("SQL: ~s~n", [SQL]),
|
||||||
@@ -705,7 +705,7 @@ wait_result(Port) ->
|
|||||||
{Port, Reply} ->
|
{Port, Reply} ->
|
||||||
% ?dbg("Reply: ~p~n", [Reply]),
|
% ?dbg("Reply: ~p~n", [Reply]),
|
||||||
Reply;
|
Reply;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
error_logger:error_msg("sqlite3 driver error: ~s~n", [Reason]),
|
error_logger:error_msg("sqlite3 driver error: ~s~n", [Reason]),
|
||||||
% ?dbg("Error: ~p~n", [Reason]),
|
% ?dbg("Error: ~p~n", [Reason]),
|
||||||
{error, Reason};
|
{error, Reason};
|
||||||
@@ -719,8 +719,8 @@ parse_table_info(Info) ->
|
|||||||
[_, Tail] = string:tokens(Info, "()"),
|
[_, Tail] = string:tokens(Info, "()"),
|
||||||
Cols = string:tokens(Tail, ","),
|
Cols = string:tokens(Tail, ","),
|
||||||
build_table_info(lists:map(fun(X) ->
|
build_table_info(lists:map(fun(X) ->
|
||||||
string:tokens(X, " ")
|
string:tokens(X, " ")
|
||||||
end, Cols), []).
|
end, Cols), []).
|
||||||
|
|
||||||
build_table_info([], Acc) ->
|
build_table_info([], Acc) ->
|
||||||
lists:reverse(Acc);
|
lists:reverse(Acc);
|
||||||
@@ -732,8 +732,8 @@ build_table_info([[ColName, ColType | Constraints] | Tl], Acc) ->
|
|||||||
%% TODO conflict-clause parsing
|
%% TODO conflict-clause parsing
|
||||||
build_constraints([]) -> [];
|
build_constraints([]) -> [];
|
||||||
build_constraints(["PRIMARY", "KEY" | Tail]) ->
|
build_constraints(["PRIMARY", "KEY" | Tail]) ->
|
||||||
{Constraint, Rest} = build_primary_key_constraint(Tail),
|
{Constraint, Rest} = build_primary_key_constraint(Tail),
|
||||||
[Constraint | build_constraints(Rest)];
|
[Constraint | build_constraints(Rest)];
|
||||||
build_constraints(["UNIQUE" | Tail]) -> [unique | build_constraints(Tail)];
|
build_constraints(["UNIQUE" | Tail]) -> [unique | build_constraints(Tail)];
|
||||||
build_constraints(["NOT", "NULL" | Tail]) -> [not_null | build_constraints(Tail)];
|
build_constraints(["NOT", "NULL" | Tail]) -> [not_null | build_constraints(Tail)];
|
||||||
build_constraints(["DEFAULT", DefaultValue | Tail]) -> [{default, sqlite3_lib:sql_to_value(DefaultValue)} | build_constraints(Tail)].
|
build_constraints(["DEFAULT", DefaultValue | Tail]) -> [{default, sqlite3_lib:sql_to_value(DefaultValue)} | build_constraints(Tail)].
|
||||||
@@ -743,15 +743,15 @@ build_constraints(["DEFAULT", DefaultValue | Tail]) -> [{default, sqlite3_lib:sq
|
|||||||
build_primary_key_constraint(Tokens) -> build_primary_key_constraint(Tokens, []).
|
build_primary_key_constraint(Tokens) -> build_primary_key_constraint(Tokens, []).
|
||||||
|
|
||||||
build_primary_key_constraint(["ASC" | Rest], Acc) ->
|
build_primary_key_constraint(["ASC" | Rest], Acc) ->
|
||||||
build_primary_key_constraint(Rest, [asc | Acc]);
|
build_primary_key_constraint(Rest, [asc | Acc]);
|
||||||
build_primary_key_constraint(["DESC" | Rest], Acc) ->
|
build_primary_key_constraint(["DESC" | Rest], Acc) ->
|
||||||
build_primary_key_constraint(Rest, [desc | Acc]);
|
build_primary_key_constraint(Rest, [desc | Acc]);
|
||||||
build_primary_key_constraint(["AUTOINCREMENT" | Rest], Acc) ->
|
build_primary_key_constraint(["AUTOINCREMENT" | Rest], Acc) ->
|
||||||
build_primary_key_constraint(Rest, [autoincrement | Acc]);
|
build_primary_key_constraint(Rest, [autoincrement | Acc]);
|
||||||
build_primary_key_constraint(Tail, []) ->
|
build_primary_key_constraint(Tail, []) ->
|
||||||
{primary_key, Tail};
|
{primary_key, Tail};
|
||||||
build_primary_key_constraint(Tail, Acc) ->
|
build_primary_key_constraint(Tail, Acc) ->
|
||||||
{{primary_key, lists:reverse(Acc)}, Tail}.
|
{{primary_key, lists:reverse(Acc)}, Tail}.
|
||||||
|
|
||||||
%% conflict_clause(["ON", "CONFLICT", ResolutionString | Tail]) ->
|
%% conflict_clause(["ON", "CONFLICT", ResolutionString | Tail]) ->
|
||||||
%% Resolution = case ResolutionString of
|
%% Resolution = case ResolutionString of
|
||||||
@@ -760,7 +760,7 @@ build_primary_key_constraint(Tail, Acc) ->
|
|||||||
%% "FAIL" -> fail;
|
%% "FAIL" -> fail;
|
||||||
%% "IGNORE" -> ignore;
|
%% "IGNORE" -> ignore;
|
||||||
%% "REPLACE" -> replace
|
%% "REPLACE" -> replace
|
||||||
%% end,
|
%% end,
|
||||||
%% {{on_conflict, Resolution}, Tail};
|
%% {{on_conflict, Resolution}, Tail};
|
||||||
%% conflict_clause(NoOnConflictClause) ->
|
%% conflict_clause(NoOnConflictClause) ->
|
||||||
%% {no_on_conflict, NoOnConflictClause}.
|
%% {no_on_conflict, NoOnConflictClause}.
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ col_type_to_atom("REAL") ->
|
|||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-spec value_to_sql_unsafe(sql_value()) -> iolist().
|
-spec value_to_sql_unsafe(sql_value()) -> iolist().
|
||||||
value_to_sql_unsafe(X) ->
|
value_to_sql_unsafe(X) ->
|
||||||
if
|
if
|
||||||
is_integer(X) -> integer_to_list(X);
|
is_integer(X) -> integer_to_list(X);
|
||||||
is_float(X) -> float_to_list(X);
|
is_float(X) -> float_to_list(X);
|
||||||
X == ?NULL_ATOM -> "NULL";
|
X == ?NULL_ATOM -> "NULL";
|
||||||
true -> [$', X, $'] %% assumes no $' inside strings!
|
true -> [$', X, $'] %% assumes no $' inside strings!
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec value_to_sql(Value :: sql_value()) -> iolist()
|
%% @spec value_to_sql(Value :: sql_value()) -> iolist()
|
||||||
@@ -84,12 +84,12 @@ value_to_sql_unsafe(X) ->
|
|||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-spec value_to_sql(sql_value()) -> iolist().
|
-spec value_to_sql(sql_value()) -> iolist().
|
||||||
value_to_sql(X) ->
|
value_to_sql(X) ->
|
||||||
if
|
if
|
||||||
is_integer(X) -> integer_to_list(X);
|
is_integer(X) -> integer_to_list(X);
|
||||||
is_float(X) -> float_to_list(X);
|
is_float(X) -> float_to_list(X);
|
||||||
X == ?NULL_ATOM -> "NULL";
|
X == ?NULL_ATOM -> "NULL";
|
||||||
true -> [$', escape(X), $']
|
true -> [$', escape(X), $']
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
@@ -99,21 +99,21 @@ value_to_sql(X) ->
|
|||||||
%% @end
|
%% @end
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
sql_to_value(String) ->
|
sql_to_value(String) ->
|
||||||
case String of
|
case String of
|
||||||
"NULL" -> null;
|
"NULL" -> null;
|
||||||
"CURRENT_TIME" -> current_time;
|
"CURRENT_TIME" -> current_time;
|
||||||
"CURRENT_DATE" -> current_date;
|
"CURRENT_DATE" -> current_date;
|
||||||
"CURRENT_TIMESTAMP" -> current_timestamp;
|
"CURRENT_TIMESTAMP" -> current_timestamp;
|
||||||
[FirstChar | Tail] ->
|
[FirstChar | Tail] ->
|
||||||
case FirstChar of
|
case FirstChar of
|
||||||
$' -> sql_string(Tail);
|
$' -> sql_string(Tail);
|
||||||
$x -> sql_blob(Tail);
|
$x -> sql_blob(Tail);
|
||||||
$X -> sql_blob(Tail);
|
$X -> sql_blob(Tail);
|
||||||
$+ -> sql_number(Tail);
|
$+ -> sql_number(Tail);
|
||||||
$- -> -sql_number(Tail);
|
$- -> -sql_number(Tail);
|
||||||
Digit when $0 =< Digit, Digit =< $9 -> sql_number(Tail)
|
Digit when $0 =< Digit, Digit =< $9 -> sql_number(Tail)
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec write_value_sql(Value :: [sql_value()]) -> iolist()
|
%% @spec write_value_sql(Value :: [sql_value()]) -> iolist()
|
||||||
@@ -125,7 +125,7 @@ sql_to_value(String) ->
|
|||||||
write_value_sql(Values) ->
|
write_value_sql(Values) ->
|
||||||
map_intersperse(fun value_to_sql/1, Values, ", ").
|
map_intersperse(fun value_to_sql/1, Values, ", ").
|
||||||
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec write_col_sql([atom()]) -> iolist()
|
%% @spec write_col_sql([atom()]) -> iolist()
|
||||||
%% @doc Creates the column/data stmt for SQL.
|
%% @doc Creates the column/data stmt for SQL.
|
||||||
@@ -154,8 +154,8 @@ escape(IoData) -> re:replace(IoData, "'", "''", [global]).
|
|||||||
-spec update_set_sql([{atom(), sql_value()}]) -> iolist().
|
-spec update_set_sql([{atom(), sql_value()}]) -> iolist().
|
||||||
update_set_sql(Data) ->
|
update_set_sql(Data) ->
|
||||||
ColValueToSqlFun =
|
ColValueToSqlFun =
|
||||||
fun({Col, Value}) ->
|
fun({Col, Value}) ->
|
||||||
[atom_to_list(Col), " = ", value_to_sql(Value)]
|
[atom_to_list(Col), " = ", value_to_sql(Value)]
|
||||||
end,
|
end,
|
||||||
map_intersperse(ColValueToSqlFun, Data, ", ").
|
map_intersperse(ColValueToSqlFun, Data, ", ").
|
||||||
|
|
||||||
@@ -199,8 +199,8 @@ create_table_sql(Tbl, Columns) ->
|
|||||||
create_table_sql(Tbl, Columns, TblConstraints) ->
|
create_table_sql(Tbl, Columns, TblConstraints) ->
|
||||||
["CREATE TABLE ", atom_to_list(Tbl), " (",
|
["CREATE TABLE ", atom_to_list(Tbl), " (",
|
||||||
map_intersperse(fun column_sql_for_create_table/1, Columns, ", "), ", ",
|
map_intersperse(fun column_sql_for_create_table/1, Columns, ", "), ", ",
|
||||||
map_intersperse(fun table_constraint_sql/1, TblConstraints, ", "),
|
map_intersperse(fun table_constraint_sql/1, TblConstraints, ", "),
|
||||||
");"].
|
");"].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec update_sql(Tbl, Key, Value, Data) -> iolist()
|
%% @spec update_sql(Tbl, Key, Value, Data) -> iolist()
|
||||||
@@ -217,7 +217,7 @@ create_table_sql(Tbl, Columns, TblConstraints) ->
|
|||||||
-spec update_sql(atom(), atom(), sql_value(), [{atom(), sql_value()}]) -> iolist().
|
-spec update_sql(atom(), atom(), sql_value(), [{atom(), sql_value()}]) -> iolist().
|
||||||
update_sql(Tbl, Key, Value, Data) ->
|
update_sql(Tbl, Key, Value, Data) ->
|
||||||
["UPDATE ", atom_to_list(Tbl), " SET ", update_set_sql(Data),
|
["UPDATE ", atom_to_list(Tbl), " SET ", update_set_sql(Data),
|
||||||
" WHERE ", atom_to_list(Key), " = ", value_to_sql(Value), ";"].
|
" WHERE ", atom_to_list(Key), " = ", value_to_sql(Value), ";"].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec write_sql(Tbl, Data) -> iolist()
|
%% @spec write_sql(Tbl, Data) -> iolist()
|
||||||
@@ -231,7 +231,7 @@ update_sql(Tbl, Key, Value, Data) ->
|
|||||||
write_sql(Tbl, Data) ->
|
write_sql(Tbl, Data) ->
|
||||||
{Cols, Values} = lists:unzip(Data),
|
{Cols, Values} = lists:unzip(Data),
|
||||||
["INSERT INTO ", atom_to_list(Tbl), " (", write_col_sql(Cols),
|
["INSERT INTO ", atom_to_list(Tbl), " (", write_col_sql(Cols),
|
||||||
") values (", write_value_sql(Values), ");"].
|
") values (", write_value_sql(Values), ");"].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec read_sql(Tbl) -> iolist()
|
%% @spec read_sql(Tbl) -> iolist()
|
||||||
@@ -254,7 +254,7 @@ read_sql(Tbl) ->
|
|||||||
-spec read_sql(atom(), [atom()]) -> iolist().
|
-spec read_sql(atom(), [atom()]) -> iolist().
|
||||||
read_sql(Tbl, Columns) ->
|
read_sql(Tbl, Columns) ->
|
||||||
["SELECT ", read_cols_sql(Columns), " FROM ",
|
["SELECT ", read_cols_sql(Columns), " FROM ",
|
||||||
atom_to_list(Tbl), ";"].
|
atom_to_list(Tbl), ";"].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec read_sql(Tbl, Key, Value) -> iolist()
|
%% @spec read_sql(Tbl, Key, Value) -> iolist()
|
||||||
@@ -268,7 +268,7 @@ read_sql(Tbl, Columns) ->
|
|||||||
-spec read_sql(atom(), atom(), sql_value()) -> iolist().
|
-spec read_sql(atom(), atom(), sql_value()) -> iolist().
|
||||||
read_sql(Tbl, Key, Value) ->
|
read_sql(Tbl, Key, Value) ->
|
||||||
["SELECT * FROM ", atom_to_list(Tbl), " WHERE ", atom_to_list(Key),
|
["SELECT * FROM ", atom_to_list(Tbl), " WHERE ", atom_to_list(Key),
|
||||||
" = ", value_to_sql(Value), ";"].
|
" = ", value_to_sql(Value), ";"].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec read_sql(Tbl, Key, Value, Columns) -> iolist()
|
%% @spec read_sql(Tbl, Key, Value, Columns) -> iolist()
|
||||||
@@ -284,8 +284,8 @@ read_sql(Tbl, Key, Value) ->
|
|||||||
-spec read_sql(atom(), atom(), sql_value(), [atom()]) -> iolist().
|
-spec read_sql(atom(), atom(), sql_value(), [atom()]) -> iolist().
|
||||||
read_sql(Tbl, Key, Value, Columns) ->
|
read_sql(Tbl, Key, Value, Columns) ->
|
||||||
["SELECT ", read_cols_sql(Columns), " FROM ",
|
["SELECT ", read_cols_sql(Columns), " FROM ",
|
||||||
atom_to_list(Tbl), " WHERE ", atom_to_list(Key), " = ",
|
atom_to_list(Tbl), " WHERE ", atom_to_list(Key), " = ",
|
||||||
value_to_sql(Value), ";"].
|
value_to_sql(Value), ";"].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec delete_sql(Tbl, Key, Value) -> iolist()
|
%% @spec delete_sql(Tbl, Key, Value) -> iolist()
|
||||||
@@ -299,7 +299,7 @@ read_sql(Tbl, Key, Value, Columns) ->
|
|||||||
-spec delete_sql(atom(), atom(), sql_value()) -> iolist().
|
-spec delete_sql(atom(), atom(), sql_value()) -> iolist().
|
||||||
delete_sql(Tbl, Key, Value) ->
|
delete_sql(Tbl, Key, Value) ->
|
||||||
["DELETE FROM ", atom_to_list(Tbl), " WHERE ", atom_to_list(Key),
|
["DELETE FROM ", atom_to_list(Tbl), " WHERE ", atom_to_list(Key),
|
||||||
" = ", value_to_sql(Value), ";"].
|
" = ", value_to_sql(Value), ";"].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @spec drop_table_sql(Tbl) -> iolist()
|
%% @spec drop_table_sql(Tbl) -> iolist()
|
||||||
@@ -324,54 +324,54 @@ map_intersperse(Fun, [Head | Tail], Sep) -> [Fun(Head), Sep | map_intersperse(Fu
|
|||||||
|
|
||||||
-spec sql_number(string()) -> number() | {error, not_a_number}.
|
-spec sql_number(string()) -> number() | {error, not_a_number}.
|
||||||
sql_number(NumberStr) ->
|
sql_number(NumberStr) ->
|
||||||
case string:to_integer(NumberStr) of
|
case string:to_integer(NumberStr) of
|
||||||
{Int, []} ->
|
{Int, []} ->
|
||||||
Int;
|
Int;
|
||||||
Other ->
|
Other ->
|
||||||
case string:to_float(NumberStr) of
|
case string:to_float(NumberStr) of
|
||||||
{Float, []} ->
|
{Float, []} ->
|
||||||
Float;
|
Float;
|
||||||
Other ->
|
Other ->
|
||||||
{error, not_a_number}
|
{error, not_a_number}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec sql_string(string()) -> binary().
|
-spec sql_string(string()) -> binary().
|
||||||
sql_string(StringWithEscapedQuotes) ->
|
sql_string(StringWithEscapedQuotes) ->
|
||||||
Res1 = re:replace(StringWithEscapedQuotes, "''", "'", [global, {return, binary}]),
|
Res1 = re:replace(StringWithEscapedQuotes, "''", "'", [global, {return, binary}]),
|
||||||
binary_part(Res1, 0, byte_size(Res1) - 1).
|
binary_part(Res1, 0, byte_size(Res1) - 1).
|
||||||
|
|
||||||
-spec sql_blob(string()) -> binary().
|
-spec sql_blob(string()) -> binary().
|
||||||
sql_blob([$' | Tail]) -> hex_str_to_bin(Tail, <<>>).
|
sql_blob([$' | Tail]) -> hex_str_to_bin(Tail, <<>>).
|
||||||
|
|
||||||
hex_str_to_bin("'", Acc) ->
|
hex_str_to_bin("'", Acc) ->
|
||||||
Acc; %% single quote at the end of blob literal
|
Acc; %% single quote at the end of blob literal
|
||||||
hex_str_to_bin([X, Y | Tail], Acc) ->
|
hex_str_to_bin([X, Y | Tail], Acc) ->
|
||||||
hex_str_to_bin(Tail, <<Acc/binary, (X * 16 + Y)>>).
|
hex_str_to_bin(Tail, <<Acc/binary, (X * 16 + Y)>>).
|
||||||
|
|
||||||
column_sql_for_create_table({Name, Type}) ->
|
column_sql_for_create_table({Name, Type}) ->
|
||||||
[atom_to_list(Name), " ", col_type_to_string(Type)];
|
[atom_to_list(Name), " ", col_type_to_string(Type)];
|
||||||
column_sql_for_create_table({Name, Type, Constraints}) ->
|
column_sql_for_create_table({Name, Type, Constraints}) ->
|
||||||
[atom_to_list(Name), " ", col_type_to_string(Type),
|
[atom_to_list(Name), " ", col_type_to_string(Type),
|
||||||
" " | map_intersperse(fun constraint_sql/1, Constraints, " ")].
|
" " | map_intersperse(fun constraint_sql/1, Constraints, " ")].
|
||||||
|
|
||||||
-spec constraint_sql(any()) -> iolist().
|
-spec constraint_sql(any()) -> iolist().
|
||||||
constraint_sql(Constraint) ->
|
constraint_sql(Constraint) ->
|
||||||
case Constraint of
|
case Constraint of
|
||||||
primary_key -> "PRIMARY KEY";
|
primary_key -> "PRIMARY KEY";
|
||||||
{primary_key, desc} -> "PRIMARY KEY DESC";
|
{primary_key, desc} -> "PRIMARY KEY DESC";
|
||||||
unique -> "UNIQUE";
|
unique -> "UNIQUE";
|
||||||
not_null -> "NOT NULL";
|
not_null -> "NOT NULL";
|
||||||
{default, DefaultValue} -> ["DEFAULT ", value_to_sql(DefaultValue)]
|
{default, DefaultValue} -> ["DEFAULT ", value_to_sql(DefaultValue)]
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec table_constraint_sql(any()) -> iolist().
|
-spec table_constraint_sql(any()) -> iolist().
|
||||||
table_constraint_sql(TableConstraint) ->
|
table_constraint_sql(TableConstraint) ->
|
||||||
case TableConstraint of
|
case TableConstraint of
|
||||||
{primary_key, Columns} -> ["PRIMARY KEY(", map_intersperse(fun indexed_column_sql/1, Columns, ", "), ")"];
|
{primary_key, Columns} -> ["PRIMARY KEY(", map_intersperse(fun indexed_column_sql/1, Columns, ", "), ")"];
|
||||||
{unique, Columns} -> ["UNIQUE(", map_intersperse(fun indexed_column_sql/1, Columns, ", "), ")"]
|
{unique, Columns} -> ["UNIQUE(", map_intersperse(fun indexed_column_sql/1, Columns, ", "), ")"]
|
||||||
%% TODO: foreign key
|
%% TODO: foreign key
|
||||||
end.
|
end.
|
||||||
|
|
||||||
indexed_column_sql({ColumnName, asc}) -> [atom_to_list(ColumnName), " ASC"];
|
indexed_column_sql({ColumnName, asc}) -> [atom_to_list(ColumnName), " ASC"];
|
||||||
indexed_column_sql({ColumnName, desc}) -> [atom_to_list(ColumnName), " DESC"];
|
indexed_column_sql({ColumnName, desc}) -> [atom_to_list(ColumnName), " DESC"];
|
||||||
@@ -395,49 +395,49 @@ indexed_column_sql(ColumnName) -> atom_to_list(ColumnName).
|
|||||||
-define(assertFlat(Expected, Value), ?assertEqual(iolist_to_binary(Expected), iolist_to_binary(Value))).
|
-define(assertFlat(Expected, Value), ?assertEqual(iolist_to_binary(Expected), iolist_to_binary(Value))).
|
||||||
|
|
||||||
quote_test() ->
|
quote_test() ->
|
||||||
?assertFlat("'abc'", value_to_sql("abc")),
|
?assertFlat("'abc'", value_to_sql("abc")),
|
||||||
?assertFlat("'a''b''''c'", value_to_sql("a'b''c")).
|
?assertFlat("'a''b''''c'", value_to_sql("a'b''c")).
|
||||||
|
|
||||||
create_table_sql_test() ->
|
create_table_sql_test() ->
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT);",
|
"CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT);",
|
||||||
create_table_sql(user, [{id, integer, [primary_key]}, {name, text}])),
|
create_table_sql(user, [{id, integer, [primary_key]}, {name, text}])),
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"CREATE TABLE user (id INTEGER, name TEXT, PRIMARY KEY(id));",
|
"CREATE TABLE user (id INTEGER, name TEXT, PRIMARY KEY(id));",
|
||||||
create_table_sql(user, [{id, integer}, {name, text}], [{primary_key, [id]}])).
|
create_table_sql(user, [{id, integer}, {name, text}], [{primary_key, [id]}])).
|
||||||
|
|
||||||
update_sql_test() ->
|
update_sql_test() ->
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"UPDATE user SET name = 'a' WHERE id = 1;",
|
"UPDATE user SET name = 'a' WHERE id = 1;",
|
||||||
update_sql(user, id, 1, [{name, "a"}])).
|
update_sql(user, id, 1, [{name, "a"}])).
|
||||||
|
|
||||||
write_sql_test() ->
|
write_sql_test() ->
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"INSERT INTO user (id, name) values (1, 'a');",
|
"INSERT INTO user (id, name) values (1, 'a');",
|
||||||
write_sql(user, [{id, 1}, {name, "a"}])).
|
write_sql(user, [{id, 1}, {name, "a"}])).
|
||||||
|
|
||||||
read_sql_test() ->
|
read_sql_test() ->
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"SELECT * FROM user;",
|
"SELECT * FROM user;",
|
||||||
read_sql(user)),
|
read_sql(user)),
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"SELECT id, name FROM user;",
|
"SELECT id, name FROM user;",
|
||||||
read_sql(user, [id, name])),
|
read_sql(user, [id, name])),
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"SELECT * FROM user WHERE id = 1;",
|
"SELECT * FROM user WHERE id = 1;",
|
||||||
read_sql(user, id, 1)),
|
read_sql(user, id, 1)),
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"SELECT id, name FROM user WHERE id = 1;",
|
"SELECT id, name FROM user WHERE id = 1;",
|
||||||
read_sql(user, id, 1, [id, name])).
|
read_sql(user, id, 1, [id, name])).
|
||||||
|
|
||||||
delete_sql_test() ->
|
delete_sql_test() ->
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"DELETE FROM user WHERE id = 1;",
|
"DELETE FROM user WHERE id = 1;",
|
||||||
delete_sql(user, id, 1)).
|
delete_sql(user, id, 1)).
|
||||||
|
|
||||||
drop_table_sql_test() ->
|
drop_table_sql_test() ->
|
||||||
?assertFlat(
|
?assertFlat(
|
||||||
"DROP TABLE user;",
|
"DROP TABLE user;",
|
||||||
drop_table_sql(user)).
|
drop_table_sql(user)).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|||||||
6
test.erl
6
test.erl
@@ -14,10 +14,10 @@ test() ->
|
|||||||
{id, Id2} = sqlite3:write(ct, user, [{name, "marge"}, {age, 30}, {wage, 2000}]),
|
{id, Id2} = sqlite3:write(ct, user, [{name, "marge"}, {age, 30}, {wage, 2000}]),
|
||||||
Id2 = 2,
|
Id2 = 2,
|
||||||
[{columns, Columns}, {rows, Rows1}] = sqlite3:sql_exec(ct, "select * from user;"),
|
[{columns, Columns}, {rows, Rows1}] = sqlite3:sql_exec(ct, "select * from user;"),
|
||||||
Columns = ["id", "name", "age", "wage"],
|
Columns = ["id", "name", "age", "wage"],
|
||||||
Rows1 = [{1, <<"abby">>, 20, 2000}, {2, <<"marge">>, 30, 2000}],
|
Rows1 = [{1, <<"abby">>, 20, 2000}, {2, <<"marge">>, 30, 2000}],
|
||||||
[{columns, Columns}, {rows, Rows2}] = sqlite3:read(ct, user, {name, "abby"}),
|
[{columns, Columns}, {rows, Rows2}] = sqlite3:read(ct, user, {name, "abby"}),
|
||||||
Rows2 = [{1, <<"abby">>, 20, 2000}],
|
Rows2 = [{1, <<"abby">>, 20, 2000}],
|
||||||
[{columns, Columns}, {rows, Rows1}] = sqlite3:read(ct, user, {wage, 2000}),
|
[{columns, Columns}, {rows, Rows1}] = sqlite3:read(ct, user, {wage, 2000}),
|
||||||
sqlite3:delete(ct, user, {name, "marge"}),
|
sqlite3:delete(ct, user, {name, "marge"}),
|
||||||
[{columns, Columns}, {rows, Rows2}] = sqlite3:sql_exec(ct, "select * from user;"),
|
[{columns, Columns}, {rows, Rows2}] = sqlite3:sql_exec(ct, "select * from user;"),
|
||||||
|
|||||||
@@ -17,30 +17,30 @@
|
|||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
drop_all_tables(Db) ->
|
drop_all_tables(Db) ->
|
||||||
Tables = sqlite3:list_tables(Db),
|
Tables = sqlite3:list_tables(Db),
|
||||||
[sqlite3:drop_table(Db, Table) || Table <- Tables],
|
[sqlite3:drop_table(Db, Table) || Table <- Tables],
|
||||||
Tables.
|
Tables.
|
||||||
|
|
||||||
drop_table_if_exists(Db, Table) ->
|
drop_table_if_exists(Db, Table) ->
|
||||||
case lists:member(Table, sqlite3:list_tables(Db)) of
|
case lists:member(Table, sqlite3:list_tables(Db)) of
|
||||||
true -> sqlite3:drop_table(Db, Table);
|
true -> sqlite3:drop_table(Db, Table);
|
||||||
false -> ok
|
false -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
rows(SqlExecReply) ->
|
rows(SqlExecReply) ->
|
||||||
[{columns, _Columns}, {rows, Rows}] = SqlExecReply,
|
[{columns, _Columns}, {rows, Rows}] = SqlExecReply,
|
||||||
Rows.
|
Rows.
|
||||||
|
|
||||||
basic_functionality_test() ->
|
basic_functionality_test() ->
|
||||||
Columns = ["id", "name", "age", "wage"],
|
Columns = ["id", "name", "age", "wage"],
|
||||||
AllRows = [{1, <<"abby">>, 20, 2000}, {2, <<"marge">>, 30, 2000}],
|
AllRows = [{1, <<"abby">>, 20, 2000}, {2, <<"marge">>, 30, 2000}],
|
||||||
AbbyOnly = [{1, <<"abby">>, 20, 2000}],
|
AbbyOnly = [{1, <<"abby">>, 20, 2000}],
|
||||||
sqlite3:open(ct),
|
sqlite3:open(ct),
|
||||||
drop_all_tables(ct),
|
drop_all_tables(ct),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
[],
|
[],
|
||||||
sqlite3:list_tables(ct)),
|
sqlite3:list_tables(ct)),
|
||||||
{ok, TableId} = sqlite3:create_table(ct, user, [{id, integer, [primary_key]}, {name, text}, {age, integer}, {wage, integer}]),
|
{ok, TableId} = sqlite3:create_table(ct, user, [{id, integer, [primary_key]}, {name, text}, {age, integer}, {wage, integer}]),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
[user],
|
[user],
|
||||||
sqlite3:list_tables(ct)),
|
sqlite3:list_tables(ct)),
|
||||||
@@ -77,38 +77,38 @@ basic_functionality_test() ->
|
|||||||
?assertEqual(
|
?assertEqual(
|
||||||
{ok, TableId},
|
{ok, TableId},
|
||||||
sqlite3:drop_table(ct, user)),
|
sqlite3:drop_table(ct, user)),
|
||||||
sqlite3:close(ct).
|
sqlite3:close(ct).
|
||||||
|
|
||||||
select_many_records_test() ->
|
select_many_records_test() ->
|
||||||
sqlite3:open(ct),
|
sqlite3:open(ct),
|
||||||
drop_table_if_exists(ct, many_records),
|
drop_table_if_exists(ct, many_records),
|
||||||
sqlite3:create_table(ct, many_records, [{id, integer}, {name, text}]),
|
sqlite3:create_table(ct, many_records, [{id, integer}, {name, text}]),
|
||||||
sqlite3:write_many(ct, many_records, [[{id, X}, {name, "bar"}] || X <- lists:seq(1, 1024)]),
|
sqlite3:write_many(ct, many_records, [[{id, X}, {name, "bar"}] || X <- lists:seq(1, 1024)]),
|
||||||
%% sqlite3:begin_transaction(ct),
|
%% sqlite3:begin_transaction(ct),
|
||||||
%% [sqlite3:write(ct, many_records, [{id, X}, {name, "bar"}]) || X <- lists:seq(1, 1024)], %% takes very long :(
|
%% [sqlite3:write(ct, many_records, [{id, X}, {name, "bar"}]) || X <- lists:seq(1, 1024)], %% takes very long :(
|
||||||
%% sqlite3:commit_transaction(ct),
|
%% sqlite3:commit_transaction(ct),
|
||||||
Columns = ["id", "name"],
|
Columns = ["id", "name"],
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
[{columns, Columns}, {rows, [{1, <<"bar">>}]}],
|
[{columns, Columns}, {rows, [{1, <<"bar">>}]}],
|
||||||
sqlite3:read(ct, many_records, {id, 1})),
|
sqlite3:read(ct, many_records, {id, 1})),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
10,
|
10,
|
||||||
length(rows(sqlite3:sql_exec(ct, "select * from many_records limit 10;")))),
|
length(rows(sqlite3:sql_exec(ct, "select * from many_records limit 10;")))),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
100,
|
100,
|
||||||
length(rows(sqlite3:sql_exec(ct, "select * from many_records limit 100;")))),
|
length(rows(sqlite3:sql_exec(ct, "select * from many_records limit 100;")))),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
1000,
|
1000,
|
||||||
length(rows(sqlite3:sql_exec(ct, "select * from many_records limit 1000;")))),
|
length(rows(sqlite3:sql_exec(ct, "select * from many_records limit 1000;")))),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
1024,
|
1024,
|
||||||
length(rows(sqlite3:sql_exec(ct, "select * from many_records;")))),
|
length(rows(sqlite3:sql_exec(ct, "select * from many_records;")))),
|
||||||
sqlite3:close(ct).
|
sqlite3:close(ct).
|
||||||
|
|
||||||
nonexistent_table_info_test() ->
|
nonexistent_table_info_test() ->
|
||||||
sqlite3:open(ct),
|
sqlite3:open(ct),
|
||||||
?assertEqual(table_does_not_exist, sqlite3:table_info(ct, nonexistent)),
|
?assertEqual(table_does_not_exist, sqlite3:table_info(ct, nonexistent)),
|
||||||
sqlite3:close(ct).
|
sqlite3:close(ct).
|
||||||
|
|
||||||
% create, read, update, delete
|
% create, read, update, delete
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user