Commit 63473dfbf3fe67d50d08dd02e6f99d5cf5ef3627

Authored by totoro
1 parent 307c3090

move the db_model.anubis to calexium_lib

calexium_lib @ aef2e7132fa
1   -Subproject commit 4d677a6833d4c02037f913f30dd460500a390bf1
  1 +Subproject commit aef2e7132faffe8125687b30c6f9867ac3ea6e93
... ...
model_manager.aproj
... ... @@ -39,9 +39,14 @@
39 39 <Compile Include="calexium_lib\database\migration_common.anubis" />
40 40 <Compile Include="calexium_lib\database\migration_common_sqlite3.anubis" />
41 41 <Compile Include="calexium_lib\database\migration_sqlite3.anubis" />
  42 + <Compile Include="calexium_lib\database\model\db_model.anubis" />
42 43 <Compile Include="calexium_lib\database\settings.anubis" />
43 44 <Compile Include="calexium_lib\database\settings_sqlite3.anubis" />
44 45 <Compile Include="calexium_lib\database\sqlite_foreign_key.anubis" />
  46 + <Compile Include="calexium_lib\database\vtm\view_table_manager.anubis" />
  47 + <Compile Include="calexium_lib\database\vtm\view_table_manager_types.anubis" />
  48 + <Compile Include="calexium_lib\database\vtm\view_table_renderer.anubis" />
  49 + <Compile Include="calexium_lib\database\vtm\view_table_types.anubis" />
45 50 <Compile Include="calexium_lib\extensions\json.anubis" />
46 51 <Compile Include="calexium_lib\mail\authentication.anubis" />
47 52 <Compile Include="calexium_lib\mail\lexers\enhanced_status.anubis" />
... ... @@ -468,7 +473,6 @@
468 473 <Compile Include="src\generation\types.anubis" />
469 474 <Compile Include="src\main.anubis" />
470 475 <Compile Include="src\model.3.0.0.anubis" />
471   - <Compile Include="src\types\db_model.anubis" />
472 476 <None Include="calexium_lib\.git" />
473 477 <None Include="calexium_lib\.gitignore" />
474 478 <None Include="calexium_lib\obj\unit_test.aproj.FileListAbsolute.txt" />
... ... @@ -625,6 +629,8 @@
625 629 <Folder Include="calexium_lib" />
626 630 <Folder Include="calexium_lib\asterisk" />
627 631 <Folder Include="calexium_lib\database" />
  632 + <Folder Include="calexium_lib\database\model" />
  633 + <Folder Include="calexium_lib\database\vtm" />
628 634 <Folder Include="calexium_lib\extensions" />
629 635 <Folder Include="calexium_lib\mail" />
630 636 <Folder Include="calexium_lib\mail\lexers" />
... ...
src/generation/files.anubis
... ... @@ -8,7 +8,7 @@
8 8  
9 9 read system/string.anubis
10 10  
11   -read types/db_model.anubis
  11 +read calexium_lib/database/model/db_model.anubis
12 12 read tools/basis.anubis
13 13 read tools/streams.anubis
14 14 read tools/ISO-8601.anubis
... ...
src/generation/header.anubis
... ... @@ -6,7 +6,7 @@
6 6 * © Calexium
7 7 */
8 8  
9   -read types/db_model.anubis
  9 +read calexium_lib/database/model/db_model.anubis
10 10 read tools/basis.anubis
11 11 read tools/streams.anubis
12 12 read tools/ISO-8601.anubis
... ... @@ -21,7 +21,7 @@ define Maybe(One)
21 21 {
22 22 [] then success(unique),
23 23 [h . t] then
24   - since h is db_column(_, type, _),
  24 + since h is db_column(_, type, _, _),
25 25 if type is foreign_key(table_name) then
26 26 if write_string(stream, "\nread database/generated/"+table_name+".anubis") is
27 27 {
... ...
src/generation/types.anubis
... ... @@ -6,7 +6,7 @@
6 6 * © Calexium
7 7 */
8 8  
9   -read types/db_model.anubis
  9 +read calexium_lib/database/model/db_model.anubis
10 10 read tools/basis.anubis
11 11 read tools/streams.anubis
12 12 read system/string.anubis
... ... @@ -24,7 +24,7 @@ define List(String)
24 24 {
25 25 [] then reverse(so_far),
26 26 [h . t ] then
27   - since h is db_column(name, col_type, _),
  27 + since h is db_column(name, col_type, _, _),
28 28 _generate_type(t, [ " "+fill(to_Anubis_type(col_type), 12) + " " + name . so_far])
29 29 }.
30 30  
... ... @@ -60,7 +60,7 @@ define List(String)
60 60 {
61 61 [] then reverse(so_far),
62 62 [h . t ] then
63   - since h is db_column(name, col_type, _),
  63 + since h is db_column(name, col_type, _, _),
64 64 _generate_get_default(t, [ to_Anubis_default(col_type) . so_far])
65 65 }.
66 66 public define Maybe(One)
... ... @@ -96,7 +96,7 @@ define (List(String), Int)
96 96 {
97 97 [] then (reverse(so_far), closure),
98 98 [h . t ] then
99   - since h is db_column(name, col_type, _),
  99 + since h is db_column(name, col_type, _, _),
100 100 with result = from_web_arg(col_type, name),
101 101 //If the field is not editable no need to get it from the web
102 102 if result = "" then
... ...
src/main.anubis
... ... @@ -15,7 +15,7 @@
15 15  
16 16 read tools/string.anubis
17 17 read generation/files.anubis
18   -read types/db_model.anubis
  18 +read calexium_lib/database/model/db_model.anubis
19 19 read model.3.0.0.anubis
20 20  
21 21 global define One
... ...
src/model.3.0.0.anubis
1 1  
2   -read types/db_model.anubis
  2 +read calexium_lib/database/model/db_model.anubis
3 3  
4 4  
5 5 public define DB_Table mf_serial_table =
... ...
src/types/db_model.anubis deleted
1   -/*
2   - * Created by PyramIDE.
3   - * User: フランスのトトロ
4   - * Date: 01/01/2016
5   - * Time: 1:34
6   - * © Calexium
7   - */
8   -
9   - The Anubis project
10   -
11   - Interfacing a database with Anubis
12   -
13   -
14   - Author: David René
15   -
16   -
17   -
18   - In order to generate such tools, DB_Model needs a formal
19   - description of the database.
20   -
21   -
22   - *** (1) Formal description of the database.
23   -
24   - *** (1.1) 'DB_Model_Field' (data types of table columns).
25   -public type DB_Datetime_Field_Attr:
26   - none, //Nothing special, normal behaviour
27   - auto_now, //Always update datetime at SQL update
28   - auto_now_add. //Set current datetime when row is created and can't be edited anymore
29   -
30   -public type DB_Model_Field:
31   - //anubis(String _T), // the datum of type _T is serialized and base64 encoded
32   - p_key,
33   - //binary, // contains a byte array
34   - boolean_field, // true or false
35   - date_field(DB_Datetime_Field_Attr), // date with the precision of the day
36   - time_field(DB_Datetime_Field_Attr), // time with the precision of the second
37   - datetime_field(DB_Datetime_Field_Attr), // datetime with the precision of the second
38   - foreign_key(String table_name), // foreign key to 'id' in another (or same) table and column_name for choice selector.
39   - integer_field, // integer of arbitrary size
40   - char_field(Int size), // text of maximal size 'size' (number of characters)
41   - text_field. // text of variable size
42   -
43   - From the point of view of your Anubis program, these data will be of types:
44   -
45   - Name | Anubis type | Type within the database
46   - ----------------+-------------------+--------------------------------------------------
47   - //anubis | T (serializable) | text (base64 encoded serialization)
48   - p_key | DB_id | primary key (integer)
49   - //binary | ByteArray | text (the byte array base64 encoded)
50   - boolean_field | Bool | boolean
51   - date_field | DB_date | text (date in ISO-8601 format: yyyy-mm-dd)
52   - time_field | DB_time | text (date in ISO-8601 format: hh:mm:ss)
53   - datetime_field | DB_datetime | text (date in ISO-8601 format: yyyy-mm-dd hh:mm:ss)
54   - foreign_key | Int | integer
55   - integer_field | Int | arbitrary size integer (numeric)
56   - char_field | String | max size text
57   - text_field | String | arbitrary size text
58   -
59   -
60   -
61   - *** (1.2) 'MaybeNull'.
62   -
63   - This type scheme is isomorphic to 'Maybe', and is used for representing data which
64   - can have the value 'NULL'. We don't use 'Maybe' for this purpose because
65   - we want to avoid the misleading 'Maybe(Maybe(...))'. Instead, we will have
66   - sometimes 'Maybe(MaybeNull(...))', so that 'null' means 'NULL', and 'failure'
67   - means an error.
68   -
69   -public type MaybeNull($T):
70   - null,
71   - not_null($T value).
72   -
73   - Conversion tools between date, time and datetime in ISO-8601 format and 'Int'
74   - (number of seconds since the epoch) are provided in 'library/tools/ISO-8601.anubis'.
75   -
76   -
77   -
78   - *** (1.3) 'DB_Model_Attr' (attributes of columns).
79   -
80   - Possible attributes of columns: (each column has a list of such attributes)
81   -
82   -public type DB_Model_Attr:
83   - unique, // by default, the values in a column are not required to be all different
84   - indexed, // by default, a column is not indexed
85   - default(String). // default value (used in case of creation of a NON NULL column
86   - // in a table which already contains some rows)
87   -
88   - Of course, 'NOT NULL' is not an alternative of 'DB_Model_Attr' because it is already coded into the
89   - database type itself (type 'DB_Model_Field' above).
90   -
91   -
92   - *** (1.4) 'DB_Model_Column' (describing a column in a table).
93   -
94   - Description of a column:
95   -
96   -public type DB_Model_Column:
97   - db_column (String name, // name of ordinary column (i.e. all but 'id')
98   - DB_Model_Field type,
99   - List(DB_Model_Attr) attributes).
100   -
101   -
102   - *** (3.7) 'DB_Model_Table' (describing a table).
103   -
104   - Description of a table:
105   -
106   -public type DB_Model:
107   - db_model( List(DB_Model_Column) columns, // columns other than the primary key column (if any)
108   - String show_string).
109   -
110   -
111   -public type DB_Display:
112   - db_display(List(String) list_view,
113   - List(String) edit_view).
114   -
115   -public type DB_Table:
116   - db_table ( String name, // name of the table
117   - DB_Model model,
118   - DB_Display display).
119   -
120   - *** (3.8) 'DB_Database' (describing a whole database).
121   -
122   - Description of a whole database:
123   -
124   -public type DB_Database:
125   - db_database (String name, // name of the database
126   - List(DB_Table) tables).
127   -// list of all tables in the database
128   -
129   -
130   -
131   -//public define Maybe(String) convert_to_date (MaybeNull(ByteArray) b).
132   -//public define MaybeNull(String) convert_to_date_or_null (MaybeNull(ByteArray) b).
133   -
134   - *** (8.3.6) Converting 'integer?' and 'integer?_or_null' to and fro.
135   -
136   - The next functions are used for integer16, integer32 and integer.
137   -
138   -//public define Maybe(Int) convert_to_integer (MaybeNull(ByteArray) b).
139   -//public define MaybeNull(Int) convert_to_integer_or_null (MaybeNull(ByteArray) b).
140   -
141   -
142   - *** (8.3.7) Converting 'char/text' and 'char_or_null/text_or_null' to and fro.
143   -
144   - The same functions are used for 'text/text_or_null' and 'vartext/vartext_or_null'.
145   -
146   - Litteral texts must be 'prepared' before they can be included into
147   - SQL commands (this amounts to doubling the single quotes).
148   -
149   - public define MetaSQL_Prepared prepare_text (String t).
150   - public define MetaSQL_Prepared prepare_text_or_null (MaybeNull(String) t).
151   -
152   - Conversely, texts arrive from the database in the form of byte arrays which must be
153   - converted to strings. The two functions for converting to 'text' and to 'text_or_null'
154   - are almost the same one. The only difference is that 'null' is interpreted as an error in
155   - the case of 'text'.
156   -
157   - --- That's all for the public part !----------------------------------------------------------------
158   -
159   -read tools/basis.anubis
160   -read tools/base64.anubis
161   -read system/string.anubis
162   -read tools/ISO-8601.anubis
163   -
164   -
165   - *** [1] Tools.
166   -
167   - *** [1.1] Concatenating strings which may not exist.
168   -
169   - The concatenation function '+' for strings is defined in 'tools/basis.anubis'. Here we define
170   - an extension of it to strings which may not exist (i.e. data of type 'Maybe(String)'). Of course,
171   - the result is always of type 'Maybe(String)'.
172   -
173   -define macro Maybe(String)
174   - Maybe(String) s + String t
175   - =
176   - if s is
177   - {
178   - failure then failure,
179   - success(s1) then success(s1+t)
180   - }.
181   -
182   -define macro Maybe(String)
183   - String s + Maybe(String) t
184   - =
185   - if t is
186   - {
187   - failure then failure,
188   - success(t1) then success(s+t1)
189   - }.
190   -
191   -define macro Maybe(String)
192   - Maybe(String) s + Maybe(String) t
193   - =
194   - if s is
195   - {
196   - failure then failure,
197   - success(s1) then if t is
198   - {
199   - failure then failure,
200   - success(t1) then success(s1+t1)
201   - }
202   - }.
203   -
204   -
205   -
206   - *** [2] Verifications concerning the description of the database and queries.
207   -
208   -
209   -
210   - define Bool
211   - has_forbidden_references
212   - (
213   - String table_name, // the first 3 arguments concern the current table.
214   - MetaSQL_PrimKey pk,
215   - List(DB_Model_Column) columns,
216   - List(DB_Model_Column) forwards, // subsequent tables
217   - List(String) backwards // list of backwards table names
218   - ) =
219   - if columns is
220   - {
221   - [ ] then false, // no forbidden reference found
222   - [col1 . other_cols] then
223   - if is_forbidden_reference(table_name,col1,forwards,backwards)
224   - then true
225   - else has_forbidden_references(table_name,pk,other_cols,forwards,backwards)
226   - }.
227   -
228   - define Bool // returns 'true' if there is at least one forbidden cycle.
229   - has_forbidden_cycles
230   - (
231   - String db_name,
232   - List(DB_Model_Column) tables,
233   - List(String) backwards // names of 'backwards' tables
234   - ) =
235   - if tables is
236   - {
237   - [ ] then false, // no forbidden cycle found
238   - [tab1 . other_tabs] then if tab1 is table(name1,pk1,cols1) then
239   - if has_forbidden_references(name1,pk1,cols1,other_tabs,backwards)
240   - then true
241   - else has_forbidden_cycles(db_name,other_tabs,[name1 . backwards])
242   - }.
243   -
244   - define Bool
245   - is_forbidden_column_name
246   - (
247   - String name
248   - ) =
249   - name = "id" | name = "metasqlcheck".
250   -
251   - define Bool
252   - has_forbidden_column_names
253   - (
254   - DB_Model_Column tab
255   - ) =
256   - if tab is table(_,_,cols) then
257   - mapor((DB_Model_Column cs) |->
258   - if cs is col(name,_,_) then is_forbidden_column_name(name),
259   - cols).
260   -
261   - define Bool
262   - has_forbidden_column_names
263   - (
264   - DB_Model_DB db
265   - ) =
266   - if db is database(_,tables) then
267   - mapor(has_forbidden_column_names,tables).
268   -
269   -
270   -
271   - *** [3] Generating the target file.
272   -
273   - *** [3.1] Converting a database type into the corresponding Anubis type:
274   -
275   -public define String
276   - to_Anubis_type
277   - (
278   - DB_Model_Field t
279   - ) =
280   - if t is
281   - {
282   - //anubis(_T) then "ByteArray",
283   - p_key then "DB_id",
284   - //binary then "ByteArray",
285   - boolean_field then "Bool",
286   - date_field(_) then "DB_date",
287   - time_field(_) then "DB_time",
288   - datetime_field(_) then "DB_datetime",
289   - foreign_key(_) then "Int",
290   - integer_field then "Int",
291   - char_field(Int size) then "String",
292   - text_field then "String"
293   - }.
294   -
295   -
296   -public define String
297   - to_Anubis_default
298   - (
299   - DB_Model_Field t
300   - ) =
301   - if t is
302   - {
303   - //anubis(_T) then "constant_byte_array(0,0)",
304   - p_key then "none",
305   - //binary then "constant_byte_array(0,0)",
306   - boolean_field then "false",
307   - date_field(_) then "db_date(\"\")",
308   - time_field(_) then "db_time(\"\")",
309   - datetime_field(_) then "db_datetime(\"\")",
310   - foreign_key(_) then "0",
311   - integer_field then "0",
312   - char_field(Int size) then "\"\"",
313   - text_field then "\"\""
314   - }.
315   -
316   -public define String
317   - from_DB_cursor
318   - (
319   - DB_Model_Field t,
320   - String cursor,
321   - Int index
322   - ) =
323   - with cursor_index = "("+cursor+")("+index+")",
324   - if t is
325   - {
326   - //anubis(_T) then "constant_byte_array(0,0)",
327   - p_key then "db_id((Int)db_integer"+cursor_index+")",
328   - //binary then "constant_byte_array(0,0)",
329   - boolean_field then "db_bool"+cursor_index,
330   - date_field(_) then "db_date(text"+cursor_index+")",
331   - time_field(_) then "db_time(text"+cursor_index+")",
332   - datetime_field(_) then "db_datetime(text"+cursor_index+")",
333   - foreign_key(_) then "(Int)db_integer"+cursor_index,
334   - integer_field then "(Int)db_integer"+cursor_index,
335   - char_field(Int size) then "text"+cursor_index,
336   - text_field then "text"+cursor_index
337   - }.
338   -
339   -define List(String)
340   -/**
341   - */
342   - components
343   - (
344   - List(DB_Model_Column) columns,
345   - String cursor_name,
346   - List(String) so_far,
347   - Int idx
348   - )=
349   - if columns is
350   - {
351   - [] then reverse(so_far),
352   - [h . t ] then
353   - since h is db_column(name, col_type, _),
354   - with line = fill(from_DB_cursor(col_type, cursor_name, idx), 35)+ "/* "+name+" */",
355   - components(t, cursor_name, [line . so_far], idx + 1 )
356   - }.
357   -
358   -public define String
359   - generate_constructor_from_cursor
360   - (
361   - String constructor_name,
362   - String cursor_name,
363   - List(DB_Model_Column) columns,
364   - String indent
365   - )=
366   - indent+constructor_name+"(\n"+indent+" "+join(",\n"+indent+" ", components(columns, cursor_name, [], 0))+"\n"+indent+")".
367   -
368   -
369   -public define String
370   - from_web_arg
371   - (
372   - DB_Model_Field t,
373   - String name
374   - ) =
375   - if t is
376   - {
377   - //anubis(_T) then "constant_byte_array(0,0)",
378   - p_key then "with "+name+" = get_DB_id(lwa, \""+name+"\"),",
379   - //binary then "constant_byte_array(0,0)",
380   - boolean_field then "with "+name+" = get_Bool(lwa, \""+name+"\"),",
381   - date_field(attrs) then if attrs = none then "get_DB_date(lwa, \""+name+"\")" else "with "+name+" = get_dummy_DB_date,",
382   - time_field(attrs) then if attrs = none then "get_DB_time(lwa, \""+name+"\")" else "with "+name+" = get_dummy_DB_time,",
383   - datetime_field(attrs) then if attrs = none then "get_DB_datetime(lwa, \""+name+"\")" else "with "+name+" = get_dummy_DB_datetime,",
384   - foreign_key(String table) then "get_Int(lwa, \""+name+"\")",
385   - integer_field then "get_Int(lwa, \""+name+"\")",
386   - char_field(Int size) then "get_String(lwa, \""+name+"\")",
387   - text_field then "get_String(lwa, \""+name+"\")"
388   - }.
389   -
390   -public define List(String)
391   -/**
392   - */
393   - components
394   - (
395   - List(DB_Model_Column) columns,
396   - List(String) so_far
397   - )=
398   - if columns is
399   - {
400   - [] then reverse(so_far),
401   - [h . t ] then
402   - since h is db_column(name, col_type, _),
403   - components(t, [ name . so_far])
404   - }.
405   -
406   -public define String
407   - generate_constructor
408   - (
409   - String constructor_name,
410   - List(DB_Model_Column) columns,
411   - String indent
412   - )=
413   - indent+constructor_name+"(\n"+indent+" "+join(",\n"+indent+" ", components(columns, []))+")".
414   -
415   -public define String
416   - to_Bind
417   - (
418   - DB_Model_Field t,
419   - String type_name, //name of the type
420   - String name, //name of component into the type
421   - Bool insert //true if insert time else false for update
422   - ) =
423   - if t is
424   - {
425   - //anubis(_T) then "constant_byte_array(0,0)",
426   - p_key then "",
427   - //binary then "constant_byte_array(0,0)",
428   - boolean_field then "bind_Bool(\":v_"+name+"\", "+type_name+"."+name+")",
429   - date_field(attrs) then "bind_Date(\":v_"+name+"\", "+type_name+"."+name+")",
430   - time_field(attrs) then "bind_Time(\":v_"+name+"\", "+type_name+"."+name+")",
431   - datetime_field(attrs) then if attrs is
432   - {
433   - none then "bind_Datetime(\":v_"+name+"\", "+type_name+"."+name+")",
434   - auto_now then "bind_Datetime(\":v_"+name+"\", now)",
435   - auto_now_add then
436   - if insert then
437   - "bind_Datetime(\":v_"+name+"\", now)"
438   - else
439   - ""
440   - },
441   - foreign_key(_) then "bind_Int(\":v_"+name+"\", "+type_name+"."+name+")",
442   - integer_field then "bind_Int(\":v_"+name+"\", "+type_name+"."+name+")",
443   - char_field(Int size) then "bind_String(\":v_"+name+"\", "+type_name+"."+name+")",
444   - text_field then "bind_String(\":v_"+name+"\", "+type_name+"."+name+")"
445   - }.
446   -
447   -public define List(String)
448   -/**
449   - */
450   - to_Bind_list
451   - (
452   - List(DB_Model_Column) columns,
453   - String type_name, //name of the type
454   - List(String) so_far,
455   - Bool insert
456   - )=
457   - if columns is
458   - {
459   - [] then reverse(so_far),
460   - [h . t ] then
461   - since h is db_column(name, col_type, _),
462   - with result = to_Bind(col_type, type_name, name, insert),
463   - //we eliminate the empty string because during the join it will have an empty line
464   - if result = "" then
465   - to_Bind_list(t, type_name, so_far, insert)
466   - else
467   - to_Bind_list(t, type_name, [result . so_far], insert)
468   - }.
469   -
470   -public define String
471   - generate_Bind_list
472   - (
473   - List(DB_Model_Column) columns,
474   - String type_name,
475   - String indent,
476   - Bool insert
477   - )=
478   - indent+"[\n"+indent+" "+join(",\n"+indent+" ", to_Bind_list(columns, type_name, [], insert))+"]".
479   -
480   -
481   -public define Maybe(String)
482   - get_column_name
483   - (
484   - DB_Model_Column col,
485   - Bool insert //true if insert time else false for update
486   - ) =
487   - since col is db_column(name, col_type, _),
488   - if col_type is
489   - {
490   - //anubis(_T) then "constant_byte_array(0,0)",
491   - p_key then failure,
492   - //binary then "constant_byte_array(0,0)",
493   - boolean_field then success(name),
494   - date_field(attrs) then success(name),
495   - time_field(attrs) then success(name),
496   - datetime_field(attrs) then if attrs is
497   - {
498   - none then success(name),
499   - auto_now then success(name),
500   - auto_now_add then
501   - if insert then success(name) else failure
502   - },
503   - foreign_key(_) then success(name),
504   - integer_field then success(name),
505   - char_field(Int size) then success(name),
506   - text_field then success(name)
507   - }.
508   -
509   -public define List(String)
510   - columns_name
511   - (
512   - List(DB_Model_Column) columns,
513   - Bool insert, //true if insert time else false for update
514   - List(String) so_far
515   - ) =
516   - if columns is
517   - {
518   - [] then reverse(so_far),
519   - [h . t] then
520   - if get_column_name(h, insert) is
521   - {
522   - failure then columns_name(t, insert, so_far)
523   - success(result) then
524   - if insert then
525   - columns_name(t, insert, [result . so_far])
526   - else
527   - columns_name(t, insert, [result+" = :v_"+result . so_far])
528   - }
529   - }.
530   -
531   -public define String
532   -/*
533   - Generate the SQL "(xxx, yyy, ...) VALUES ( :v_xxx, :v_yyy, ...)" for the insert
534   - SQL query.
535   - */
536   - insert_values
537   - (
538   - List(DB_Model_Column) columns,
539   - String indent
540   - )=
541   - with columns_list = columns_name(columns, true, []),
542   - indent+" ("+join(", ", columns_list)+")\n"+indent+"VALUES\n"+indent+" ("+prefixed_join(":v_", columns_list, ", ")+")".
543   -
544   -
545   -public define String
546   -/*
547   - Generate the SQL "xxx = :v_xxx, yyy = :v_yyy, ..." for the update
548   - SQL query.
549   - */
550   - update_values
551   - (
552   - List(DB_Model_Column) columns,
553   - String indent
554   - )=
555   - with columns_list = columns_name(columns, false, []),
556   - indent+" "+join(", ", columns_list).
557   -
558   -
559   -public define Maybe(String)
560   - get_VT_edit_entry
561   - (
562   - DB_Model_Column col,
563   - String type_name
564   - ) =
565   - since col is db_column(name, col_type, _),
566   - if col_type is
567   - {
568   - //anubis(_T) then "constant_byte_array(0,0)",
569   - p_key then success("primary_key(to_String("+type_name+"."+name+"))"),
570   - //binary then "constant_byte_array(0,0)",
571   - boolean_field then success("boolean(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+")"),
572   - date_field(attrs) then success("date(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+")"),
573   - time_field(attrs) then success("time(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+")"),
574   - datetime_field(attrs) then if attrs is
575   - {
576   - none then success("datetime(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".datetime)"),
577   - auto_now then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".datetime)"),
578   - auto_now_add then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".datetime)")
579   - },
580   - foreign_key(_) then success("information(\"FOREIGN_TODO\", \""+name+"\", to_String("+type_name+"."+name+"))"),
581   - integer_field then success("integer(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+")"),
582   - char_field(Int size) then success("text(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+")"),
583   - text_field then success("text_area(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+")")
584   - }.
585   -
586   -public define String
587   - edit_entries
588   - (
589   - List(DB_Model_Column) columns,
590   - String type_name,
591   - String indent,
592   - List(String) so_far
593   - ) =
594   - if columns is
595   - {
596   - [] then indent+" "+join(",\n"+indent+" ", reverse(so_far)),
597   - [h . t] then
598   - if get_VT_edit_entry(h, type_name) is
599   - {
600   - failure then edit_entries(t, type_name, indent, so_far)
601   - success(result) then edit_entries(t, type_name, indent, [result . so_far])
602   - }
603   - }.
604   -
605   -public define String
606   - make_list_view_header
607   - (
608   - List(String) list_view,
609   - String indent
610   - )=
611   - indent+join(",\n"+indent, map((String text) |-> "text(\""+to_upper(text)+"\")", list_view)).
612   -
613   -public define Maybe(DB_Model_Column)
614   - get_column_type
615   - (
616   - List(DB_Model_Column) columns, //columns in wich we search
617   - String name_to_find //Column name to find in previous list
618   - )=
619   - if columns is
620   - {
621   - [] then failure,
622   - [h . t] then
623   - since h is db_column(name, field, attr),
624   - if name_to_find = name then
625   - success(h)
626   - else
627   - get_column_type(t, name_to_find)
628   - }.
629   -
630   -public define String
631   - to_cell_view
632   - (
633   - DB_Model_Column col,
634   - String type_name
635   - ) =
636   - since col is db_column(name, col_type, _),
637   - if col_type is
638   - {
639   - //anubis(_T) then "constant_byte_array(0,0)",
640   - p_key then "link(to_String("+type_name+".id), to_String("+type_name+".id))",
641   - //binary then "constant_byte_array(0,0)",
642   - boolean_field then "text(to_String("+type_name+"."+name+"))",
643   - date_field(attrs) then "text(to_String("+type_name+"."+name+"))",
644   - time_field(attrs) then "text(to_String("+type_name+"."+name+"))",
645   - datetime_field(attrs) then "text(to_String("+type_name+"."+name+"))"
646   - foreign_key(foreign_table) then "text(get_"+foreign_table+"_show_string(db, "+type_name+"."+name+"))",
647   - integer_field then "text(to_String("+type_name+"."+name+"))",
648   - char_field(Int size) then "text("+type_name+"."+name+")",
649   - text_field then "text("+type_name+"."+name+")"
650   - }.
651   -
652   -public define String
653   - to_cell_view
654   - (
655   - List(DB_Model_Column) columns,
656   - String column_name,
657   - String data_name
658   - )=
659   - if get_column_type(columns, column_name) is
660   - {
661   - failure then "column name "+column_name+"doesn't exist",
662   - success(column) then to_cell_view(column, data_name)
663   - }.
664   -
665   -public define String
666   - make_list_view_row
667   - (
668   - DB_Model model,
669   - List(String) list_view,
670   - String data_name,
671   - String indent
672   - )=
673   - since model is db_model(columns, _),
674   - indent+join(",\n"+indent, map((String column_name) |-> to_cell_view(columns, column_name, data_name), list_view)).