list_tables/1 now returns table names as they were first given.

The create_table/3 function will cast all table names to binaries, allowing
them to be given as atoms, binaries or strings. In order to recall what the
original type was, the CREATE TABLE statement includes a constant CHECK
constraint, e.g. CHECK('bin'='bin'), which is then parsed by the list_tables
function. The constraint is put last in the statement, and should not
interfere with any other constraints. Hopefully, the sqlite compiler is good
enough that this constant expression doesn't add too much overhead. :)
This commit is contained in:
Ulf Wiger
2012-02-24 09:11:24 +01:00
parent 6986d0bbde
commit bfbf038873
2 changed files with 33 additions and 7 deletions

View File

@@ -863,10 +863,10 @@ handle_call(close, _From, State) ->
Reply = ok,
{stop, normal, Reply, State};
handle_call(list_tables, _From, State) ->
SQL = "select name from sqlite_master where type='table';",
SQL = "select name, sql from sqlite_master where type='table';",
Data = do_sql_exec(SQL, State),
TableList = proplists:get_value(rows, Data),
TableNames = [erlang:list_to_atom(erlang:binary_to_list(Name)) || {Name} <- TableList],
TableNames = [cast_table_name(Name, SQLx) || {Name,SQLx} <- TableList],
{reply, TableNames, State};
handle_call({table_info, Tbl}, _From, State) when is_atom(Tbl) ->
% make sure we only get table info.
@@ -1242,6 +1242,20 @@ build_primary_key_constraint(Tail, []) ->
build_primary_key_constraint(Tail, Acc) ->
{{primary_key, lists:reverse(Acc)}, Tail}.
cast_table_name(Bin, SQL) ->
case re:run(SQL,<<"CHECK\\((.*)=(.*)\\)\\)">>,[{capture,all_but_first,binary}]) of
{match, [<<"'bin'">>, <<"'bin'">>]} ->
Bin;
{match, [<<"'lst'">>, <<"'lst'">>]} ->
binary_to_atom(Bin, latin1);
{match, [<<"'am'">>, <<"'am'">>]} ->
binary_to_atom(Bin, latin1);
_ ->
%% backwards compatible
binary_to_atom(Bin, latin1)
end.
%% conflict_clause(["ON", "CONFLICT", ResolutionString | Tail]) ->
%% Resolution = case ResolutionString of
%% "ROLLBACK" -> rollback;