erlydb patch for erlydb:code_gen [field orderring and transient fields], test app

4 views
Skip to first unread message

John Webb

unread,
Dec 7, 2008, 9:08:26 AM12/7/08
to erl...@googlegroups.com, Yariv Sadan
Hello,

Following the posting of some erlydb_mnesia patches I've been playing
with erlyweb and was disconcerted to find that the erlydb_test app no
longer passes all its tests in v0.7.

1. When a component's fields/0 function is overridden then, in the
generated code, the component's fields are treated as being ordered
alphabetically and not in the order returned by the Module:fields/0
(nor even the underlying database order). I found this very counter
intuitive. The erlydb documentation implies that the generated
functions honor the field order defined by Module:fields/0.

2. Calling one of the find functions for a component which defines
"transient" fields raises an exception.

The attached patch proposes some fixes to the above but I am sure
there is plenty of room for improvement. With the patch applied the
test suite runs to completion for both mnesia and mysql on Mac OS.

List of Changes:
- src/erlydb/erlydb.erl
- preserve field order defined in Module:fields/0
- throw error if fields() contains duplicate field names

- src/erlyfb/erlydb_base:
- find functions return 'undefined' value for transient
fields (not actually covered by the test suite)

- src/erlydb/erlydb_mnesia.erl:
- Michael Mullis's get_metadata patch
- include {order_by,atom()} default clause (required by test
suite)

- test/erlydb/erlydb_test:
- reorder arguments in call to erlydb:code_gen/3 (changed in
v0.7)


Perhaps Yariv, or someone, could comment as to whether I am on track
here or what I have probably missed...

Thanks,
John

=============================================================
diff --git a/src/erlydb/erlydb.erl b/src/erlydb/erlydb.erl
index b3ed408..3b27525 100644
--- a/src/erlydb/erlydb.erl
+++ b/src/erlydb/erlydb.erl
@@ -568,10 +568,21 @@ get_db_fields(Module, DbFields) ->
'*' -> [set_attributes(Field, []) || Field <- DbFields];
DefinedFields ->
DefinedFields1 =
- lists:map(fun({_Name, _Atts} = F) -> F;
- (Name) -> {Name, []}
- end, lists:usort(DefinedFields)),
-
+ %% Normalize the list of fields
+ %% Throw an error if any field is duplicated
+ lists:foldr(fun({Name, _Atts} = F, Acc) ->
+ case lists:keymember(Name, 1, Acc) of
+ true ->
+ exit({duplicate_field,{"fields/0 returns duplicate field",F}});
+ false ->
+ [F|Acc]
+ end
+ end,
+ [],
+ lists:map(fun({_Name, _Atts} = F) -> F;
+ (Name) -> {Name, []}
+ end, DefinedFields)),
+
PkFields = [{erlydb_field:name(Field), []} ||
Field <- DbFields,
erlydb_field:key(Field) == primary,
diff --git a/src/erlydb/erlydb_base.erl b/src/erlydb/erlydb_base.erl
index 477329d..b422201 100644
--- a/src/erlydb/erlydb_base.erl
+++ b/src/erlydb/erlydb_base.erl
@@ -1735,7 +1735,16 @@ field_names_for_query(Module, UseStar) ->
Module:db_field_names()
end;
_Fields ->
- Module:db_field_names()
+ lists:map(fun(Field) ->
+ case erlydb_field:is_transient(Field) of
+ true ->
+ undefined;
+ false ->
+ erlydb_field:name(Field)
+ end
+ end,
+ Module:db_fields())
+
end.


diff --git a/src/erlydb/erlydb_mnesia.erl b/src/erlydb/erlydb_mnesia.erl
index bd7a136..4d19266 100644
--- a/src/erlydb/erlydb_mnesia.erl
+++ b/src/erlydb/erlydb_mnesia.erl
@@ -184,11 +184,10 @@ start(_Options) ->
get_metadata(_Options) ->
% NOTE Integration with mnesia_rdbms would be interesting...
Tables = mnesia:system_info(tables) -- [schema],
- Tree = lists:foldl(
+ lists:foldl(
fun(Table, TablesTree) ->
gb_trees:enter(Table, get_metadata(Table,
table_fields(Table)), TablesTree)
- end, gb_trees:empty(), Tables),
- {ok, Tree}.
+ end, gb_trees:empty(), Tables).

get_metadata(Table, Fields) when is_list(Fields) ->
[get_metadata(Table, Field) || Field <- Fields];
@@ -509,7 +508,9 @@ extras([Extra | Extras], QHDesc) ->
extras([], QHDesc) ->
QHDesc;

-extras({order_by, {Field, Order}}, #qhdesc{metadata = QLCData} =
QHDesc) when is_atom(Field) ->
+extras({order_by, Field}, QHDesc) when is_atom(Field) ->
+ extras({order_by, {Field, asc}}, QHDesc);
+extras({order_by, {Field, Order}}, #qhdesc{metadata = QLCData} =
QHDesc) ->
QHDesc#qhdesc{postqh =
fun(QH, QHOptions) ->
[Table | _Rest] = dict:fetch(tables, QLCData),
diff --git a/test/erlydb/erlydb_test.erl b/test/erlydb/erlydb_test.erl
index 7f0ff12..9931107 100644
--- a/test/erlydb/erlydb_test.erl
+++ b/test/erlydb/erlydb_test.erl
@@ -31,8 +31,9 @@ erlydb_psql_init() ->


code_gen(Database) ->
- erlydb:code_gen(Database, [language, project, developer,
musician, employee,
- person, customer, store, item], []).
+ Components = [language, project, developer, musician,
+ employee, person, customer, store, item],
+ erlydb:code_gen(Components, Database, []).

test() ->
test(mysql).


erlydb.patch
Reply all
Reply to author
Forward
0 new messages