Skip to content

Commit 887fd40

Browse files
committed
Add auto key generation to mysql
1 parent e4a2252 commit 887fd40

8 files changed

Lines changed: 441 additions & 139 deletions

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ compile: rebar3
66
$(REBAR) compile
77

88
run: rebar3
9-
$(REBAR) shell --config sample.config
9+
$(REBAR) as dev shell --config priv/sample.config --eval "sql_bridge:start(), sync:go()."
1010

1111
test: rebar3 setup-all-tests
1212
$(REBAR) eunit

src/sql_bridge.erl

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ start() ->
134134
{ok, _} = application:ensure_all_started(sql_bridge),
135135
build_stringify(),
136136
build_alias(),
137+
%% This line is for uuid generation (if you're using the auto-generation)
138+
quickrand:seed(),
137139
ok = ?ADAPTER:start(),
138140
ok.
139141

@@ -197,7 +199,7 @@ save_record(Table, KeyField, Record, FieldMap) ->
197199
save_(Table,PropList) when is_atom(Table) ->
198200
save_(atom_to_list(Table),PropList);
199201
save_(Table,PropList) when is_list(Table) ->
200-
KeyField = Table ++ "id",
202+
KeyField = primary_key(Table),
201203
save_(Table,KeyField,PropList).
202204

203205
save_(Table,KeyField,PropList) when is_atom(Table) ->
@@ -213,7 +215,22 @@ save_(Table,KeyField,PropList) when is_list(Table) ->
213215
Zero == null;
214216
Zero == "";
215217
Zero == <<>> ->
216-
pli(Table,lists:keydelete(KeyField,1,PropList));
218+
219+
PropList2 = lists:keydelete(KeyField, 1, PropList),
220+
case is_auto_increment(Table, KeyField) of
221+
true ->
222+
%% if it's auto_increment, then the removed keyfield will be taken care of
223+
pli(Table,PropList2);
224+
false ->
225+
%% if it's not auto_increment, then we will auto_increment
226+
%% based on the settings
227+
{DB, Table2} = table_and_db(Table),
228+
{AutoKeyMod, AutoKeyFun} = sql_bridge_utils:auto_increment_function(),
229+
KeyVal = AutoKeyMod:AutoKeyFun(DB, Table2),
230+
PropList3 = [{KeyField, KeyVal} | PropList2],
231+
pli(Table, PropList3),
232+
KeyVal
233+
end;
217234
_ ->
218235
plu(Table,KeyField,PropList)
219236
end.
@@ -326,12 +343,12 @@ pli(Table,InitPropList0) ->
326343
qi(SQL, Values).
327344

328345
-spec plu(Table :: table(), PropList :: proplist_or_map()) -> affected_rows().
329-
%% @doc Updates a row from the proplist based on the key `Table ++ "id"` in the Table
346+
%% @doc Updates a row from the proplist based on the primary_key in the Table
330347
plu(Table,PropList) when is_atom(Table) ->
331348
plu(atom_to_list(Table),PropList);
332349
plu(Table,PropList0) ->
333350
PropList = ensure_proplist(PropList0),
334-
KeyField = list_to_atom(Table ++ "id"),
351+
KeyField = primary_key(Table),
335352
plu(Table,KeyField,PropList).
336353

337354
-spec plu(Table :: table(), KeyField :: field(), PropList :: proplist()) -> affected_rows().
@@ -514,6 +531,10 @@ table_fields(Table0) ->
514531
<<" order by ordinal_position">>],
515532
[sql_bridge_utils:to_atom(F) || F <- ffl(SQL, [DB, Table])].
516533

534+
table_and_db(Table) when is_atom(Table) ->
535+
table_and_db(atom_to_list(Table));
536+
table_and_db(Table) when is_binary(Table) ->
537+
table_and_db(binary_to_list(Table));
517538
table_and_db(Table) ->
518539
case string:tokens(Table, ".") of
519540
[DB, TableOnly] ->
@@ -526,6 +547,20 @@ table_and_db(Table) ->
526547
fields(Table) ->
527548
table_fields(Table).
528549

550+
primary_key(Table0) ->
551+
{DB, Table} = table_and_db(Table0),
552+
case ?ADAPTER:primary_key(DB, Table) of
553+
undefined -> list_to_atom(sql_bridge_utils:to_string(Table) ++ "id");
554+
KeyField -> KeyField
555+
end.
556+
557+
is_auto_increment(Table0, Field) ->
558+
{DB, Table} = table_and_db(Table0),
559+
case ?ADAPTER:is_auto_increment(DB, Table, Field) of
560+
undefined -> true;
561+
Bool -> Bool
562+
end.
563+
529564
field_exists(Table0, Field) ->
530565
{DB, Table} = table_and_db(Table0),
531566
[T1, T2, T3] = sql_bridge_utils:create_placeholders(3),
@@ -557,7 +592,7 @@ qexists(Q,ParamList) ->
557592
exists(Table, IDValue) when is_atom(Table) ->
558593
exists(atom_to_list(Table), IDValue);
559594
exists(Table, IDValue) when is_list(Table) ->
560-
exists(Table, Table ++ "id", IDValue).
595+
exists(Table, primary_key(Table), IDValue).
561596

562597
-spec exists(Table :: table(), KeyField :: field(), IDValue :: value()) -> boolean().
563598
%% @doc Returns true if Table has a record where KeyField = IDValue
@@ -583,18 +618,18 @@ field(Table,Field,IDField,IDValue) ->
583618
fffr(["select ",Field," from ",Table," where ",IDField,"= ",Token],[IDValue]).
584619

585620
-spec field(Table :: table(), Field :: field(), Value :: value()) -> value() | not_found.
586-
%% @doc This does the same as above, but uses Table ++ "id" for the idfield
621+
%% @doc This does the same as above, but determines the primary_key
587622
field(Table,Field,IDValue) when is_atom(Table) ->
588623
field(atom_to_list(Table),Field,IDValue);
589624
field(Table,Field,IDValue) ->
590-
field(Table,Field,Table ++ "id",IDValue).
625+
field(Table,Field,primary_key(Table),IDValue).
591626

592627
-spec delete(Table :: table(), ID :: value()) -> affected_rows().
593-
%% @doc Deletes rows from Table where the Table ++ "id" = ID
628+
%% @doc Deletes rows from Table where the primary_key = ID
594629
delete(Table,ID) when is_atom(Table) ->
595630
delete(atom_to_list(Table),ID);
596631
delete(Table,ID) when is_list(Table) ->
597-
KeyField = Table ++ "id",
632+
KeyField = primary_key(Table),
598633
delete(Table,KeyField,ID).
599634

600635
-spec delete(Table :: table(), KeyField :: field(), ID :: value()) -> affected_rows().

src/sql_bridge_adapter.erl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,14 @@
1515
-callback schema_db_column() -> ColumnName :: string().
1616

1717
-callback encode(V :: any()) -> binary().
18+
19+
-callback primary_key(DB :: sql_bridge:db(),
20+
Table :: sql_bridge:table()) -> sql_bridge:field().
21+
22+
-callback get_field_type(DB :: sql_bridge:db(),
23+
Table :: sql_bridge:table(),
24+
Field :: sql_bridge:field()) -> undefined | {sql_bridge:field_type(), sql_bridge:field_details()}.
25+
26+
-callback is_auto_increment(DB :: sql_bridge:db(),
27+
Table :: sql_bridge:table(),
28+
Field :: sql_bridge:field()) -> boolean().

src/sql_bridge_epgsql.erl

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
commit_transaction/1,
1212
rollback_transaction/1,
1313
with_transaction/2,
14-
wrap_field/1
14+
wrap_field/1,
15+
primary_key/2,
16+
is_auto_increment/3,
17+
get_field_type/3,
18+
autokey/2
1519
]).
1620

1721
start() ->
@@ -232,3 +236,15 @@ escape_binary(<<X/utf8, Rest/binary>>, Acc) ->
232236
escape_binary(<<>>, Acc) ->
233237
Acc.
234238

239+
240+
primary_key(_DB, _Table) ->
241+
undefined.
242+
243+
is_auto_increment(_DB, _Table, _Field) ->
244+
undefined.
245+
246+
get_field_type(_DB, _Table, _Field) ->
247+
undefined.
248+
249+
autokey(_DB, _Table) ->
250+
undefined.

0 commit comments

Comments
 (0)