Commit 18b5b14f0141c6f970edb5467cada467d142f514
1 parent
30bc3c98
retrieve all generation part of old calexium_lib db_model.anubis and split code …
…into separate specialized source
Showing
17 changed files
with
714 additions
and
22 deletions
Show diff stats
.gitmodules
| 1 | [submodule "calexium_lib"] | 1 | [submodule "calexium_lib"] |
| 2 | path = calexium_lib | 2 | path = calexium_lib |
| 3 | url = ssh://git@gitlab.calexium.com:33022/calexium/calexium_lib.git | 3 | url = ssh://git@gitlab.calexium.com:33022/calexium/calexium_lib.git |
| 4 | +[submodule "hayamiki_lib"] | ||
| 5 | + path = hayamiki_lib | ||
| 6 | + url = ssh://git@gitlab.calexium.com:33022/calexium/hayamiki_lib.git |
calexium_lib @ ac555606b82
hayamiki.aproj
| @@ -118,6 +118,17 @@ | @@ -118,6 +118,17 @@ | ||
| 118 | <Compile Include="calexium_lib\web\widgets\dashboard.anubis" /> | 118 | <Compile Include="calexium_lib\web\widgets\dashboard.anubis" /> |
| 119 | <Compile Include="calexium_lib\web\widgets\fisheye_menu.anubis" /> | 119 | <Compile Include="calexium_lib\web\widgets\fisheye_menu.anubis" /> |
| 120 | <Compile Include="calexium_lib\web\widgets\icons_set.anubis" /> | 120 | <Compile Include="calexium_lib\web\widgets\icons_set.anubis" /> |
| 121 | + <Compile Include="hayamiki_lib\hk_generator.anubis" /> | ||
| 122 | + <Compile Include="hayamiki_lib\types\hayamiki.anubis" /> | ||
| 123 | + <Compile Include="hayamiki_lib\types\model\app.anubis" /> | ||
| 124 | + <Compile Include="hayamiki_lib\types\model\columns.anubis" /> | ||
| 125 | + <Compile Include="hayamiki_lib\types\model\database.anubis" /> | ||
| 126 | + <Compile Include="hayamiki_lib\types\model\display.anubis" /> | ||
| 127 | + <Compile Include="hayamiki_lib\types\model\fields.anubis" /> | ||
| 128 | + <Compile Include="hayamiki_lib\types\model\help.anubis" /> | ||
| 129 | + <Compile Include="hayamiki_lib\types\model\icons.anubis" /> | ||
| 130 | + <Compile Include="hayamiki_lib\types\model\model.anubis" /> | ||
| 131 | + <Compile Include="hayamiki_lib\types\model\tables.anubis" /> | ||
| 121 | <Compile Include="library\a2a\C\formater.anubis" /> | 132 | <Compile Include="library\a2a\C\formater.anubis" /> |
| 122 | <Compile Include="library\a2a\example.anubis" /> | 133 | <Compile Include="library\a2a\example.anubis" /> |
| 123 | <Compile Include="library\a2a\generic\preformater.anubis" /> | 134 | <Compile Include="library\a2a\generic\preformater.anubis" /> |
| @@ -469,13 +480,19 @@ | @@ -469,13 +480,19 @@ | ||
| 469 | <Compile Include="library\xml\basic_xml_parser.anubis" /> | 480 | <Compile Include="library\xml\basic_xml_parser.anubis" /> |
| 470 | <Compile Include="library\xml\xml_parser.apg.anubis" /> | 481 | <Compile Include="library\xml\xml_parser.apg.anubis" /> |
| 471 | <Compile Include="src\check.anubis" /> | 482 | <Compile Include="src\check.anubis" /> |
| 483 | + <Compile Include="src\generation\columns.anubis" /> | ||
| 472 | <Compile Include="src\generation\create_table.anubis" /> | 484 | <Compile Include="src\generation\create_table.anubis" /> |
| 485 | + <Compile Include="src\generation\fields.anubis" /> | ||
| 473 | <Compile Include="src\generation\files.anubis" /> | 486 | <Compile Include="src\generation\files.anubis" /> |
| 474 | <Compile Include="src\generation\header.anubis" /> | 487 | <Compile Include="src\generation\header.anubis" /> |
| 488 | + <Compile Include="src\generation\html.anubis" /> | ||
| 489 | + <Compile Include="src\generation\icons.anubis" /> | ||
| 475 | <Compile Include="src\generation\menu.anubis" /> | 490 | <Compile Include="src\generation\menu.anubis" /> |
| 491 | + <Compile Include="src\generation\model.anubis" /> | ||
| 476 | <Compile Include="src\generation\types.anubis" /> | 492 | <Compile Include="src\generation\types.anubis" /> |
| 477 | <Compile Include="src\main.anubis" /> | 493 | <Compile Include="src\main.anubis" /> |
| 478 | <Compile Include="src\model.3.0.0.anubis" /> | 494 | <Compile Include="src\model.3.0.0.anubis" /> |
| 495 | + <Compile Include="src\utils\utils.anubis" /> | ||
| 479 | <None Include="calexium_lib\.git" /> | 496 | <None Include="calexium_lib\.git" /> |
| 480 | <None Include="calexium_lib\.gitignore" /> | 497 | <None Include="calexium_lib\.gitignore" /> |
| 481 | <None Include="calexium_lib\obj\unit_test.aproj.FileListAbsolute.txt" /> | 498 | <None Include="calexium_lib\obj\unit_test.aproj.FileListAbsolute.txt" /> |
| @@ -651,6 +668,11 @@ | @@ -651,6 +668,11 @@ | ||
| 651 | <Folder Include="calexium_lib\web\jQuery\ui-addon" /> | 668 | <Folder Include="calexium_lib\web\jQuery\ui-addon" /> |
| 652 | <Folder Include="calexium_lib\web\js" /> | 669 | <Folder Include="calexium_lib\web\js" /> |
| 653 | <Folder Include="calexium_lib\web\widgets" /> | 670 | <Folder Include="calexium_lib\web\widgets" /> |
| 671 | + <Folder Include="hayamiki_lib" /> | ||
| 672 | + <Folder Include="hayamiki_lib\types" /> | ||
| 673 | + <Folder Include="hayamiki_lib\types\model" /> | ||
| 674 | + <Folder Include="hayamiki_lib\types\controler" /> | ||
| 675 | + <Folder Include="hayamiki_lib\types\view" /> | ||
| 654 | <Folder Include="library" /> | 676 | <Folder Include="library" /> |
| 655 | <Folder Include="library\a2a" /> | 677 | <Folder Include="library\a2a" /> |
| 656 | <Folder Include="library\a2a\C" /> | 678 | <Folder Include="library\a2a\C" /> |
| @@ -697,5 +719,6 @@ | @@ -697,5 +719,6 @@ | ||
| 697 | <Folder Include="library\xml" /> | 719 | <Folder Include="library\xml" /> |
| 698 | <Folder Include="src" /> | 720 | <Folder Include="src" /> |
| 699 | <Folder Include="src\generation" /> | 721 | <Folder Include="src\generation" /> |
| 722 | + <Folder Include="src\utils" /> | ||
| 700 | </ItemGroup> | 723 | </ItemGroup> |
| 701 | </Project> | 724 | </Project> |
| 702 | \ No newline at end of file | 725 | \ No newline at end of file |
hayamiki_lib @ 5982fb919cc
| 1 | +Subproject commit 5982fb919cc198b09154cab6aca30f83eadb5ef7 |
src/check.anubis
| @@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
| 6 | * © Calexium | 6 | * © Calexium |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | -read calexium_lib/database/model/db_model.anubis | 9 | +read hayamiki_lib/types/hayamiki.anubis |
| 10 | read system/string.anubis | 10 | read system/string.anubis |
| 11 | read tools/list.anubis | 11 | read tools/list.anubis |
| 12 | read tools/basis.anubis | 12 | read tools/basis.anubis |
| 1 | +/* | ||
| 2 | + * Created by PyramIDE. | ||
| 3 | + * User: フランスのトトロ aka (David RENÉ) | ||
| 4 | + * Date: 13/02/2016 | ||
| 5 | + * Time: 11:05 | ||
| 6 | + * © Calexium | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +read hayamiki_lib/types/model/columns.anubis | ||
| 10 | + | ||
| 11 | +define List(String) | ||
| 12 | +/* return the list of all columns name | ||
| 13 | + */ | ||
| 14 | + _to_List_String | ||
| 15 | + ( | ||
| 16 | + List(HK_Model_Column) columns, | ||
| 17 | + Bool with_pk, | ||
| 18 | + List(String) so_far | ||
| 19 | + )= | ||
| 20 | + if columns is | ||
| 21 | + { | ||
| 22 | + [] then reverse(so_far), | ||
| 23 | + [h . t ] then | ||
| 24 | + since h is hk_column(name, _, _, _), | ||
| 25 | + if name = "id" & with_pk = false then | ||
| 26 | + _to_List_String(t, with_pk, so_far) | ||
| 27 | + else | ||
| 28 | + _to_List_String(t, with_pk, [ name . so_far]) | ||
| 29 | + }. | ||
| 30 | + | ||
| 31 | +public define List(String) | ||
| 32 | +/* return the list of all columns name | ||
| 33 | + */ | ||
| 34 | + to_List_String | ||
| 35 | + ( | ||
| 36 | + List(HK_Model_Column) columns, | ||
| 37 | + Bool with_pk | ||
| 38 | + )= | ||
| 39 | + _to_List_String(columns, with_pk, []). | ||
| 40 | + | ||
| 41 | + | ||
| 42 | +define List(String) | ||
| 43 | +/** | ||
| 44 | + */ | ||
| 45 | + components | ||
| 46 | + ( | ||
| 47 | + List(HK_Model_Column) columns, | ||
| 48 | + String cursor_name, | ||
| 49 | + List(String) so_far, | ||
| 50 | + Int idx | ||
| 51 | + )= | ||
| 52 | + if columns is | ||
| 53 | + { | ||
| 54 | + [] then reverse(so_far), | ||
| 55 | + [h . t ] then | ||
| 56 | + since h is hk_column(name, col_type, _, _), | ||
| 57 | + with line = fill(from_DB_cursor(col_type, cursor_name, idx), 35)+ "/* "+name+" */", | ||
| 58 | + components(t, cursor_name, [line . so_far], idx + 1 ) | ||
| 59 | + }. | ||
| 60 | + | ||
| 61 | +public define String | ||
| 62 | + generate_constructor_from_cursor | ||
| 63 | + ( | ||
| 64 | + String constructor_name, | ||
| 65 | + String cursor_name, | ||
| 66 | + List(HK_Model_Column) columns, | ||
| 67 | + String indent | ||
| 68 | + )= | ||
| 69 | + indent+constructor_name+"(\n"+indent+" "+join(",\n"+indent+" ", components(columns, cursor_name, [], 0))+"\n"+indent+")". | ||
| 70 | + | ||
| 71 | +public define String | ||
| 72 | + generate_constructor | ||
| 73 | + ( | ||
| 74 | + String constructor_name, | ||
| 75 | + List(HK_Model_Column) columns, | ||
| 76 | + String indent | ||
| 77 | + )= | ||
| 78 | + indent+constructor_name+"(\n"+indent+" "+join(",\n"+indent+" ", to_List_String(columns, true))+")". | ||
| 79 | + | ||
| 80 | +public define List(String) | ||
| 81 | +/** | ||
| 82 | + */ | ||
| 83 | + to_Bind_list | ||
| 84 | + ( | ||
| 85 | + List(HK_Model_Column) columns, | ||
| 86 | + String type_name, //name of the type | ||
| 87 | + List(String) so_far, | ||
| 88 | + Bool insert | ||
| 89 | + )= | ||
| 90 | + if columns is | ||
| 91 | + { | ||
| 92 | + [] then reverse(so_far), | ||
| 93 | + [h . t ] then | ||
| 94 | + since h is hk_column(name, col_type, _, _), | ||
| 95 | + with result = to_Bind(col_type, type_name, name, insert), | ||
| 96 | + //we eliminate the empty string because during the join it will have an empty line | ||
| 97 | + if result = "" then | ||
| 98 | + to_Bind_list(t, type_name, so_far, insert) | ||
| 99 | + else | ||
| 100 | + to_Bind_list(t, type_name, [result . so_far], insert) | ||
| 101 | + }. | ||
| 102 | + | ||
| 103 | +public define String | ||
| 104 | + generate_Bind_list | ||
| 105 | + ( | ||
| 106 | + List(HK_Model_Column) columns, | ||
| 107 | + String type_name, | ||
| 108 | + String indent, | ||
| 109 | + Bool insert | ||
| 110 | + )= | ||
| 111 | + indent+"[\n"+indent+" "+join(",\n"+indent+" ", to_Bind_list(columns, type_name, [], insert))+"]". | ||
| 112 | + | ||
| 113 | + | ||
| 114 | +public define Maybe(String) | ||
| 115 | + get_column_name | ||
| 116 | + ( | ||
| 117 | + HK_Model_Column col, | ||
| 118 | + Bool insert //true if insert time else false for update | ||
| 119 | + ) = | ||
| 120 | + since col is hk_column(name, col_type, _, _), | ||
| 121 | + if col_type is | ||
| 122 | + { | ||
| 123 | + //anubis(_T) then "constant_byte_array(0,0)", | ||
| 124 | + p_key then failure, | ||
| 125 | + //binary then "constant_byte_array(0,0)", | ||
| 126 | + boolean_field then success(name), | ||
| 127 | + date_field(attrs) then success(name), | ||
| 128 | + time_field(attrs) then success(name), | ||
| 129 | + datetime_field(attrs) then if attrs is | ||
| 130 | + { | ||
| 131 | + none then success(name), | ||
| 132 | + auto_now then success(name), | ||
| 133 | + auto_now_add then | ||
| 134 | + if insert then success(name) else failure | ||
| 135 | + }, | ||
| 136 | + foreign_key(_,_) then success(name), | ||
| 137 | + integer_field then success(name), | ||
| 138 | + char_field(Int size) then success(name), | ||
| 139 | + text_field then success(name) | ||
| 140 | + }. | ||
| 141 | + | ||
| 142 | +public define List(String) | ||
| 143 | + columns_name | ||
| 144 | + ( | ||
| 145 | + List(HK_Model_Column) columns, | ||
| 146 | + Bool insert, //true if insert time else false for update | ||
| 147 | + List(String) so_far | ||
| 148 | + ) = | ||
| 149 | + if columns is | ||
| 150 | + { | ||
| 151 | + [] then reverse(so_far), | ||
| 152 | + [h . t] then | ||
| 153 | + if get_column_name(h, insert) is | ||
| 154 | + { | ||
| 155 | + failure then columns_name(t, insert, so_far) | ||
| 156 | + success(result) then | ||
| 157 | + if insert then | ||
| 158 | + columns_name(t, insert, [result . so_far]) | ||
| 159 | + else | ||
| 160 | + columns_name(t, insert, [enclose("\\\"",result)+" = :v_"+result . so_far]) | ||
| 161 | + } | ||
| 162 | + }. | ||
| 163 | + | ||
| 164 | +public define String | ||
| 165 | +/* | ||
| 166 | + Generate the SQL "(xxx, yyy, ...) VALUES ( :v_xxx, :v_yyy, ...)" for the insert | ||
| 167 | + SQL query. | ||
| 168 | + */ | ||
| 169 | + insert_values | ||
| 170 | + ( | ||
| 171 | + List(HK_Model_Column) columns, | ||
| 172 | + String indent | ||
| 173 | + )= | ||
| 174 | + with columns_list = columns_name(columns, true, []), | ||
| 175 | + indent+" ("+join(", ", enclose("\\\"",columns_list))+")\n"+indent+"VALUES\n"+indent+" ("+prefixed_join(":v_", columns_list, ", ")+")". | ||
| 176 | + | ||
| 177 | + | ||
| 178 | +public define String | ||
| 179 | +/* | ||
| 180 | + Generate the SQL "xxx = :v_xxx, yyy = :v_yyy, ..." for the update | ||
| 181 | + SQL query. | ||
| 182 | + */ | ||
| 183 | + update_values | ||
| 184 | + ( | ||
| 185 | + List(HK_Model_Column) columns, | ||
| 186 | + String indent | ||
| 187 | + )= | ||
| 188 | + with columns_list = columns_name(columns, false, []), | ||
| 189 | + indent+" "+join(", ", columns_list). | ||
| 190 | + | ||
| 191 | + | ||
| 192 | +public define Maybe(String) | ||
| 193 | + get_VT_edit_entry | ||
| 194 | + ( | ||
| 195 | + HK_Model_Column col, | ||
| 196 | + String type_name | ||
| 197 | + ) = | ||
| 198 | + since col is hk_column(name, col_type, _, help), | ||
| 199 | + if col_type is | ||
| 200 | + { | ||
| 201 | + //anubis(_T) then "constant_byte_array(0,0)", | ||
| 202 | + p_key then success("primary_key(to_String("+type_name+"."+name+"))"), | ||
| 203 | + //binary then "constant_byte_array(0,0)", | ||
| 204 | + boolean_field then success("boolean(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+", "+to_Anubis_source(help)+")"), | ||
| 205 | + date_field(attrs) then if attrs is | ||
| 206 | + { | ||
| 207 | + none then success("date(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".date, "+to_Anubis_source(help)+")"), | ||
| 208 | + auto_now then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".date, "+to_Anubis_source(help)+")"), | ||
| 209 | + auto_now_add then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".date, "+to_Anubis_source(help)+")") | ||
| 210 | + }, | ||
| 211 | + time_field(attrs) then if attrs is | ||
| 212 | + { | ||
| 213 | + none then success("time(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".time, "+to_Anubis_source(help)+")"), | ||
| 214 | + auto_now then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".time, "+to_Anubis_source(help)+")"), | ||
| 215 | + auto_now_add then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".time, "+to_Anubis_source(help)+")") | ||
| 216 | + }, | ||
| 217 | + datetime_field(attrs) then if attrs is | ||
| 218 | + { | ||
| 219 | + none then success("datetime(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".datetime, "+to_Anubis_source(help)+")"), | ||
| 220 | + auto_now then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".datetime, "+to_Anubis_source(help)+")"), | ||
| 221 | + auto_now_add then success("information(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+".datetime, "+to_Anubis_source(help)+")") | ||
| 222 | + }, | ||
| 223 | + foreign_key(app,foreign_table) then success("foreign_text(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+", vt_edit_selector(get_selector_"+foreign_table+"), "+to_Anubis_source(help)+")"), | ||
| 224 | + integer_field then success("integer(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+", "+to_Anubis_source(help)+")"), | ||
| 225 | + char_field(Int size) then success("text(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+", "+to_Anubis_source(help)+")"), | ||
| 226 | + text_field then success("text_area(\""+to_upper(name)+"\", \""+name+"\", "+type_name+"."+name+", "+to_Anubis_source(help)+")") | ||
| 227 | + }. | ||
| 228 | + | ||
| 229 | +public define String | ||
| 230 | + edit_entries | ||
| 231 | + ( | ||
| 232 | + List(HK_Model_Column) columns, | ||
| 233 | + String type_name, | ||
| 234 | + String indent, | ||
| 235 | + List(String) so_far | ||
| 236 | + ) = | ||
| 237 | + if columns is | ||
| 238 | + { | ||
| 239 | + [] then indent+" "+join(",\n"+indent+" ", reverse(so_far)), | ||
| 240 | + [h . t] then | ||
| 241 | + if get_VT_edit_entry(h, type_name) is | ||
| 242 | + { | ||
| 243 | + failure then edit_entries(t, type_name, indent, so_far) | ||
| 244 | + success(result) then edit_entries(t, type_name, indent, [result . so_far]) | ||
| 245 | + } | ||
| 246 | + }. | ||
| 247 | + | ||
| 248 | +public define String | ||
| 249 | + make_list_view_header | ||
| 250 | + ( | ||
| 251 | + List(String) list_view, | ||
| 252 | + String indent | ||
| 253 | + )= | ||
| 254 | + indent+join(",\n"+indent, map((String text) |-> "text(\""+to_upper(text)+"\")", list_view)). | ||
| 255 | + | ||
| 256 | +public define Maybe(HK_Model_Column) | ||
| 257 | + get_column_type | ||
| 258 | + ( | ||
| 259 | + List(HK_Model_Column) columns, //columns in wich we search | ||
| 260 | + String name_to_find //Column name to find in previous list | ||
| 261 | + )= | ||
| 262 | + if columns is | ||
| 263 | + { | ||
| 264 | + [] then failure, | ||
| 265 | + [h . t] then | ||
| 266 | + since h is hk_column(name, _, _, _), | ||
| 267 | + if name_to_find = name then | ||
| 268 | + success(h) | ||
| 269 | + else | ||
| 270 | + get_column_type(t, name_to_find) | ||
| 271 | + }. | ||
| 272 | + | ||
| 273 | +public define String | ||
| 274 | +/** to_String return the String of the given model of the column 'col' | ||
| 275 | + */ | ||
| 276 | + to_String | ||
| 277 | + ( | ||
| 278 | + HK_Model_Column col, | ||
| 279 | + String current_type_name, | ||
| 280 | + String general_type_name | ||
| 281 | + ) = | ||
| 282 | + since col is hk_column(name, col_type, _, _), | ||
| 283 | + if col_type is | ||
| 284 | + { | ||
| 285 | + //anubis(_T) then "constant_byte_array(0,0)", | ||
| 286 | + p_key then "get_"+general_type_name+"_show_string(db, "+current_type_name+".id)", | ||
| 287 | + //binary then "constant_byte_array(0,0)", | ||
| 288 | + boolean_field then "to_String("+current_type_name+"."+name+")", | ||
| 289 | + date_field(attrs) then "to_String("+current_type_name+"."+name+")", | ||
| 290 | + time_field(attrs) then "to_String("+current_type_name+"."+name+")", | ||
| 291 | + datetime_field(attrs) then "to_String("+current_type_name+"."+name+")" | ||
| 292 | + foreign_key(app,foreign_table) then "get_"+foreign_table+"_show_string(db, "+current_type_name+"."+name+")", | ||
| 293 | + integer_field then "to_String("+current_type_name+"."+name+")", | ||
| 294 | + char_field(Int size) then current_type_name+"."+name, | ||
| 295 | + text_field then current_type_name+"."+name | ||
| 296 | + }. |
| 1 | +/* | ||
| 2 | + * Created by PyramIDE. | ||
| 3 | + * User: フランスのトトロ aka (David RENÉ) | ||
| 4 | + * Date: 13/02/2016 | ||
| 5 | + * Time: 10:50 | ||
| 6 | + * © Calexium | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +read hayamiki_lib/types/model/fields.anubis | ||
| 10 | + | ||
| 11 | +public define String | ||
| 12 | + to_Anubis_type | ||
| 13 | + ( | ||
| 14 | + HK_Model_Field t | ||
| 15 | + ) = | ||
| 16 | + if t is | ||
| 17 | + { | ||
| 18 | + //anubis(_T) then "ByteArray", | ||
| 19 | + p_key then "DB_id", | ||
| 20 | + //binary then "ByteArray", | ||
| 21 | + boolean_field then "Bool", | ||
| 22 | + date_field(_) then "DB_date", | ||
| 23 | + time_field(_) then "DB_time", | ||
| 24 | + datetime_field(_) then "DB_datetime", | ||
| 25 | + foreign_key(_,_) then "Int", | ||
| 26 | + integer_field then "Int", | ||
| 27 | + char_field(Int size) then "String", | ||
| 28 | + text_field then "String" | ||
| 29 | + }. | ||
| 30 | + | ||
| 31 | +public define String | ||
| 32 | + to_SQL_CREATE | ||
| 33 | + ( | ||
| 34 | + HK_Model_Field t, | ||
| 35 | + List(HK_Model_Attr) attributes, | ||
| 36 | + ) = | ||
| 37 | + if t is | ||
| 38 | + { | ||
| 39 | + //anubis(_T) then "ByteArray", | ||
| 40 | + p_key then fill("INTEGER", 15) +" PRIMARY KEY", | ||
| 41 | + boolean_field then fill("BOOL", 15) +format_attributes(attributes), | ||
| 42 | + date_field(_) then fill("DATE", 15) +format_attributes(attributes), | ||
| 43 | + time_field(_) then fill("TIME", 15) +format_attributes(attributes), | ||
| 44 | + datetime_field(_) then fill("DATETIME", 15)+format_attributes(attributes), | ||
| 45 | + foreign_key(app,fk) then fill("INTEGER", 15) +" NOT NULL REFERENCES "+fk+" (id)", | ||
| 46 | + integer_field then fill("INTEGER", 15) +format_attributes(attributes), | ||
| 47 | + char_field(Int size) then fill("VARCHAR("+size+")", 15) +format_attributes(attributes), | ||
| 48 | + text_field then fill("TEXT", 15) +format_attributes(attributes), | ||
| 49 | + }. | ||
| 50 | + | ||
| 51 | +public define String | ||
| 52 | + to_Anubis_default | ||
| 53 | + ( | ||
| 54 | + HK_Model_Field t | ||
| 55 | + ) = | ||
| 56 | + if t is | ||
| 57 | + { | ||
| 58 | + //anubis(_T) then "constant_byte_array(0,0)", | ||
| 59 | + p_key then "none", | ||
| 60 | + //binary then "constant_byte_array(0,0)", | ||
| 61 | + boolean_field then "false", | ||
| 62 | + date_field(_) then "db_date(\"\")", | ||
| 63 | + time_field(_) then "db_time(\"\")", | ||
| 64 | + datetime_field(_) then "db_datetime(\"\")", | ||
| 65 | + foreign_key(_,_) then "(Int)0", | ||
| 66 | + integer_field then "(Int)0", | ||
| 67 | + char_field(Int size) then "\"\"", | ||
| 68 | + text_field then "\"\"" | ||
| 69 | + }. | ||
| 70 | + | ||
| 71 | +public define String | ||
| 72 | + from_web_arg | ||
| 73 | + ( | ||
| 74 | + HK_Model_Field t, | ||
| 75 | + String name | ||
| 76 | + ) = | ||
| 77 | + if t is | ||
| 78 | + { | ||
| 79 | + //anubis(_T) then "constant_byte_array(0,0)", | ||
| 80 | + p_key then "with "+name+" = get_DB_id(lwa, \""+name+"\"),", | ||
| 81 | + //binary then "constant_byte_array(0,0)", | ||
| 82 | + boolean_field then "with "+name+" = get_Bool(lwa, \""+name+"\"),", | ||
| 83 | + date_field(attrs) then if attrs = none then "get_DB_date(lwa, \""+name+"\")" else "with "+name+" = get_dummy_DB_date,", | ||
| 84 | + time_field(attrs) then if attrs = none then "get_DB_time(lwa, \""+name+"\")" else "with "+name+" = get_dummy_DB_time,", | ||
| 85 | + datetime_field(attrs) then if attrs = none then "get_DB_datetime(lwa, \""+name+"\")" else "with "+name+" = get_dummy_DB_datetime,", | ||
| 86 | + foreign_key(_,_) then "get_Int(lwa, \""+name+"\")", | ||
| 87 | + integer_field then "get_Int(lwa, \""+name+"\")", | ||
| 88 | + char_field(Int size) then "get_String(lwa, \""+name+"\")", | ||
| 89 | + text_field then "get_String(lwa, \""+name+"\")" | ||
| 90 | + }. | ||
| 91 | + | ||
| 92 | +public define String | ||
| 93 | + from_DB_cursor | ||
| 94 | + ( | ||
| 95 | + HK_Model_Field t, | ||
| 96 | + String cursor, //db cursor name | ||
| 97 | + Int index //current index of the column in the cursor | ||
| 98 | + ) = | ||
| 99 | + with cursor_index = "("+cursor+")("+index+")", | ||
| 100 | + if t is | ||
| 101 | + { | ||
| 102 | + p_key then "db_id((Int)db_integer"+cursor_index+")", | ||
| 103 | + boolean_field then "db_bool"+cursor_index, | ||
| 104 | + date_field(_) then "db_date(text"+cursor_index+")", | ||
| 105 | + time_field(_) then "db_time(text"+cursor_index+")", | ||
| 106 | + datetime_field(_) then "db_datetime(text"+cursor_index+")", | ||
| 107 | + foreign_key(_,_) then "(Int)db_integer"+cursor_index, | ||
| 108 | + integer_field then "(Int)db_integer"+cursor_index, | ||
| 109 | + char_field(Int size) then "text"+cursor_index, | ||
| 110 | + text_field then "text"+cursor_index | ||
| 111 | + }. | ||
| 112 | + | ||
| 113 | +public define String | ||
| 114 | + to_Bind | ||
| 115 | + ( | ||
| 116 | + HK_Model_Field t, | ||
| 117 | + String type_name, //name of the type | ||
| 118 | + String name, //name of component into the type | ||
| 119 | + Bool insert //true if insert time else false for update | ||
| 120 | + ) = | ||
| 121 | + if t is | ||
| 122 | + { | ||
| 123 | + //anubis(_T) then "constant_byte_array(0,0)", | ||
| 124 | + p_key then "", | ||
| 125 | + //binary then "constant_byte_array(0,0)", | ||
| 126 | + boolean_field then "bind_Bool(\":v_"+name+"\", "+type_name+"."+name+")", | ||
| 127 | + date_field(attrs) then "bind_Date(\":v_"+name+"\", "+type_name+"."+name+")", | ||
| 128 | + time_field(attrs) then "bind_Time(\":v_"+name+"\", "+type_name+"."+name+")", | ||
| 129 | + datetime_field(attrs) then if attrs is | ||
| 130 | + { | ||
| 131 | + none then "bind_Datetime(\":v_"+name+"\", "+type_name+"."+name+")", | ||
| 132 | + auto_now then "bind_Datetime(\":v_"+name+"\", now)", | ||
| 133 | + auto_now_add then | ||
| 134 | + if insert then | ||
| 135 | + "bind_Datetime(\":v_"+name+"\", now)" | ||
| 136 | + else | ||
| 137 | + "" | ||
| 138 | + }, | ||
| 139 | + foreign_key(_,_) then "bind_Int(\":v_"+name+"\", "+type_name+"."+name+")", | ||
| 140 | + integer_field then "bind_Int(\":v_"+name+"\", "+type_name+"."+name+")", | ||
| 141 | + char_field(Int size) then "bind_String(\":v_"+name+"\", "+type_name+"."+name+")", | ||
| 142 | + text_field then "bind_String(\":v_"+name+"\", "+type_name+"."+name+")" | ||
| 143 | + }. |
src/generation/files.anubis
| @@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
| 9 | read system/string.anubis | 9 | read system/string.anubis |
| 10 | read system/files.anubis | 10 | read system/files.anubis |
| 11 | 11 | ||
| 12 | -read calexium_lib/database/model/db_model.anubis | 12 | +read hayamiki_lib/types/hayamiki.anubis |
| 13 | read tools/basis.anubis | 13 | read tools/basis.anubis |
| 14 | read tools/streams.anubis | 14 | read tools/streams.anubis |
| 15 | read tools/ISO-8601.anubis | 15 | read tools/ISO-8601.anubis |
| @@ -168,15 +168,16 @@ define One | @@ -168,15 +168,16 @@ define One | ||
| 168 | _make_vtm(apps, [], [], [], [], []). | 168 | _make_vtm(apps, [], [], [], [], []). |
| 169 | 169 | ||
| 170 | 170 | ||
| 171 | -public define One | 171 | +define Maybe(One) |
| 172 | generate_model_files | 172 | generate_model_files |
| 173 | ( | 173 | ( |
| 174 | - HK_Database db //database model description | 174 | + HK_Database db, //database model description |
| 175 | + String destination_dir | ||
| 175 | )= | 176 | )= |
| 176 | 177 | ||
| 177 | if check_database(db) is | 178 | if check_database(db) is |
| 178 | { | 179 | { |
| 179 | - failure then println("Check database error"), | 180 | + failure then println("Check database error");failure, |
| 180 | success(database) then | 181 | success(database) then |
| 181 | since database is hk_database(name, apps), | 182 | since database is hk_database(name, apps), |
| 182 | println("Generating models for Database "+name); | 183 | println("Generating models for Database "+name); |
| @@ -184,9 +185,14 @@ public define One | @@ -184,9 +185,14 @@ public define One | ||
| 184 | println("Generating VTM for Database "+name); | 185 | println("Generating VTM for Database "+name); |
| 185 | make_vtm(apps); | 186 | make_vtm(apps); |
| 186 | println("Generating create for Database "+name); | 187 | println("Generating create for Database "+name); |
| 187 | - if generate_create_table(apps) is failure then println("failure") else | 188 | + if generate_create_table(apps) is failure then println("failure");failure else |
| 188 | println("Generating menu for Database "+name); | 189 | println("Generating menu for Database "+name); |
| 189 | - if generate_menus(apps) is failure then println("failure") else | ||
| 190 | - unique | 190 | + if generate_menus(apps) is failure then println("failure");failure else |
| 191 | + success(unique) | ||
| 191 | }. | 192 | }. |
| 192 | 193 | ||
| 194 | + | ||
| 195 | +global define HK_API | ||
| 196 | + hk_gen = | ||
| 197 | + hk_api(generate_model_files). | ||
| 198 | + |
src/generation/header.anubis
| @@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
| 6 | * © Calexium | 6 | * © Calexium |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | -read calexium_lib/database/model/db_model.anubis | 9 | +read hayamiki_lib/types/hayamiki.anubis |
| 10 | read tools/basis.anubis | 10 | read tools/basis.anubis |
| 11 | read tools/streams.anubis | 11 | read tools/streams.anubis |
| 12 | read tools/ISO-8601.anubis | 12 | read tools/ISO-8601.anubis |
| 1 | +/* | ||
| 2 | + * Created by PyramIDE. | ||
| 3 | + * User: フランスのトトロ aka (David RENÉ) | ||
| 4 | + * Date: 13/02/2016 | ||
| 5 | + * Time: 11:19 | ||
| 6 | + * © Calexium | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +read hayamiki_lib/types/model/columns.anubis | ||
| 10 | +read icons.anubis | ||
| 11 | + | ||
| 12 | +public define String | ||
| 13 | + to_HTML_cell_icon | ||
| 14 | + ( | ||
| 15 | + HK_Model_Column column, | ||
| 16 | + String data_name, | ||
| 17 | + String general_type_name | ||
| 18 | + )= | ||
| 19 | + "icon("+to_Icon(column, data_name, general_type_name)+")". | ||
| 20 | + | ||
| 21 | +public define String | ||
| 22 | + to_HTML_cell_text | ||
| 23 | + ( | ||
| 24 | + HK_Model_Column column, | ||
| 25 | + String data_name, | ||
| 26 | + String general_type_name | ||
| 27 | + )= | ||
| 28 | + "text("+to_String(column, data_name, general_type_name)+")". | ||
| 29 | + | ||
| 30 | +public define String | ||
| 31 | + to_HTML_cell_link | ||
| 32 | + ( | ||
| 33 | + HK_Model_Column column, | ||
| 34 | + String data_name, | ||
| 35 | + String general_type_name | ||
| 36 | + )= | ||
| 37 | + "link(to_String("+data_name+".id), "+to_String(column, data_name, general_type_name)+")". | ||
| 38 | + | ||
| 39 | +public define String | ||
| 40 | + to_HTML_cell_link | ||
| 41 | + ( | ||
| 42 | + List(HK_Model_Column) columns, | ||
| 43 | + String column_name, | ||
| 44 | + String data_name, | ||
| 45 | + String general_type_name | ||
| 46 | + )= | ||
| 47 | + if get_column_type(columns, column_name) is | ||
| 48 | + { | ||
| 49 | + failure then "column name "+column_name+"doesn't exist", | ||
| 50 | + success(column) then to_HTML_cell_link(column, data_name, general_type_name) | ||
| 51 | + }. | ||
| 52 | + | ||
| 53 | + | ||
| 54 | + | ||
| 55 | +public define String | ||
| 56 | + to_HTML_cell | ||
| 57 | + ( | ||
| 58 | + List(HK_Model_Column) columns, | ||
| 59 | + String column_name, | ||
| 60 | + String data_name, | ||
| 61 | + String general_type_name | ||
| 62 | + )= | ||
| 63 | + if get_column_type(columns, column_name) is | ||
| 64 | + { | ||
| 65 | + failure then "column name "+column_name+"doesn't exist", | ||
| 66 | + success(column) then | ||
| 67 | + since column is hk_column(name, col_type, _, _), | ||
| 68 | + if col_type is | ||
| 69 | + { | ||
| 70 | + p_key then to_HTML_cell_link(column, data_name, general_type_name), | ||
| 71 | + boolean_field then to_HTML_cell_icon(column, data_name, general_type_name), | ||
| 72 | + date_field(attrs) then to_HTML_cell_text(column, data_name, general_type_name), | ||
| 73 | + time_field(attrs) then to_HTML_cell_text(column, data_name, general_type_name), | ||
| 74 | + datetime_field(attrs) then to_HTML_cell_text(column, data_name, general_type_name), | ||
| 75 | + foreign_key(app,foreign_table) then to_HTML_cell_text(column, data_name, general_type_name), | ||
| 76 | + integer_field then to_HTML_cell_text(column, data_name, general_type_name), | ||
| 77 | + char_field(Int size) then to_HTML_cell_text(column, data_name, general_type_name), | ||
| 78 | + text_field then to_HTML_cell_text(column, data_name, general_type_name), | ||
| 79 | + } | ||
| 80 | + }. | ||
| 81 | + | ||
| 82 | +public define String | ||
| 83 | + make_list_view_row | ||
| 84 | + ( | ||
| 85 | + HK_Table table, //table to format | ||
| 86 | + String data_name, //name of data | ||
| 87 | + String indent, //indentation string to use | ||
| 88 | + HK_List_View list_view //list view to generate | ||
| 89 | + )= | ||
| 90 | + since table is hk_table(table_name, short, model, _), //get name and model of the table | ||
| 91 | + since model is hk_model( columns, _), //get all columns of table | ||
| 92 | +// since display is db_display(views, _), // | ||
| 93 | + with current_list_column = if list_view is | ||
| 94 | + { | ||
| 95 | + list_view_all then to_List_String(columns, false), //generate a list of columns string to view from columns model | ||
| 96 | + list_view(v_name, v_col) then v_col | ||
| 97 | + }, | ||
| 98 | + | ||
| 99 | + if current_list_column is | ||
| 100 | + { | ||
| 101 | + [] then "", | ||
| 102 | + [h . t] then | ||
| 103 | + indent+join(",\n"+indent, | ||
| 104 | + //Make first column as link | ||
| 105 | + [to_HTML_cell_link(columns, h, data_name, table_name)] + | ||
| 106 | + | ||
| 107 | + //and the other set with list_view | ||
| 108 | + map((String column_name) |-> to_HTML_cell(columns, column_name, data_name, table_name), t) | ||
| 109 | + ) | ||
| 110 | + }. |
| 1 | +/* | ||
| 2 | + * Created by PyramIDE. | ||
| 3 | + * User: フランスのトトロ aka (David RENÉ) | ||
| 4 | + * Date: 13/02/2016 | ||
| 5 | + * Time: 11:15 | ||
| 6 | + * © Calexium | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +read hayamiki_lib/types/model/columns.anubis | ||
| 10 | + | ||
| 11 | +public define String | ||
| 12 | +/** to_String return the String of the given model of the column 'col' | ||
| 13 | + */ | ||
| 14 | + to_Icon | ||
| 15 | + ( | ||
| 16 | + HK_Model_Column col, | ||
| 17 | + String current_type_name, | ||
| 18 | + String general_type_name | ||
| 19 | + ) = | ||
| 20 | + since col is hk_column(name, col_type, _, _), | ||
| 21 | + if col_type is | ||
| 22 | + { | ||
| 23 | + p_key then icn16_key, | ||
| 24 | + boolean_field then "to_Icon("+current_type_name+"."+name+")", | ||
| 25 | + date_field(attrs) then icn16_clock, | ||
| 26 | + time_field(attrs) then icn16_clock, | ||
| 27 | + datetime_field(attrs) then icn16_clock, | ||
| 28 | + foreign_key(app,foreign_table) then icn16_question, | ||
| 29 | + integer_field then icn16_question, | ||
| 30 | + char_field(Int size) then icn16_question, | ||
| 31 | + text_field then icn16_question | ||
| 32 | + }. | ||
| 33 | + |
src/generation/menu.anubis
| @@ -5,7 +5,8 @@ | @@ -5,7 +5,8 @@ | ||
| 5 | * Time: 15:40 | 5 | * Time: 15:40 |
| 6 | * © Calexium | 6 | * © Calexium |
| 7 | */ | 7 | */ |
| 8 | -read calexium_lib/database/model/db_model.anubis | 8 | + |
| 9 | +read hayamiki_lib/types/hayamiki.anubis | ||
| 9 | read tools/basis.anubis | 10 | read tools/basis.anubis |
| 10 | read tools/int.anubis | 11 | read tools/int.anubis |
| 11 | read system/string.anubis | 12 | read system/string.anubis |
| @@ -41,9 +42,9 @@ define String | @@ -41,9 +42,9 @@ define String | ||
| 41 | since display is hk_display(list_views, _), | 42 | since display is hk_display(list_views, _), |
| 42 | map((HK_List_View view ) |-> | 43 | map((HK_List_View view ) |-> |
| 43 | with view_name = if view is list_view(v_name, _) then v_name else "default", | 44 | with view_name = if view is list_view(v_name, _) then v_name else "default", |
| 44 | - indent+" "+"hk_menu_item("+fill_or_cut("\""+table_name+"\",",max_space, ' ')+ "\"view_table\", "+ | 45 | + indent+" "+"hk_menu_item("+fill("\""+table_name+"\",",max_space)+ "\"view_table\", "+ |
| 45 | fill_or_cut("\""+short_name+(if view_name="default" then "" else " "+view_name)+"\",",max_space, ' ')+ | 46 | fill_or_cut("\""+short_name+(if view_name="default" then "" else " "+view_name)+"\",",max_space, ' ')+ |
| 46 | - "[(\"table_name\", "+fill_or_cut("\""+table_name+"\",",max_space, ' ')+"),(\"view_name\", \""+view_name+"\")])", list_views), tables))+"\n"+indent+"])", apps)). | 47 | + "[(\"table_name\", "+fill("\""+table_name+"\",",max_space)+"),(\"view_name\", \""+view_name+"\")])", list_views), tables))+"\n"+indent+"])", apps)). |
| 47 | 48 | ||
| 48 | 49 | ||
| 49 | public define Maybe(One) | 50 | public define Maybe(One) |
| 1 | +/* | ||
| 2 | + * Created by PyramIDE. | ||
| 3 | + * User: フランスのトトロ aka (David RENÉ) | ||
| 4 | + * Date: 13/02/2016 | ||
| 5 | + * Time: 11:01 | ||
| 6 | + * © Calexium | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +define String | ||
| 11 | + format_attributes | ||
| 12 | + ( | ||
| 13 | + List(HK_Model_Attr) attributes | ||
| 14 | + )= | ||
| 15 | + join(" ",map((HK_Model_Attr attr) |-> | ||
| 16 | + if attr is | ||
| 17 | + { | ||
| 18 | + unique then "UNIQUE", | ||
| 19 | + indexed then "INDEXED", // by default, a column is not indexed | ||
| 20 | + default(str) then "DEFAULT "+str, // default value (used in case of creation of a NON NULL column | ||
| 21 | + // in a table which already contains some rows) | ||
| 22 | + not_null then "NOT NULL" | ||
| 23 | + }, attributes)). | ||
| 24 | + |
src/generation/types.anubis
| @@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
| 6 | * © Calexium | 6 | * © Calexium |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | -read calexium_lib/database/model/db_model.anubis | 9 | +read hayamiki_lib/types/hayamiki.anubis |
| 10 | read tools/basis.anubis | 10 | read tools/basis.anubis |
| 11 | read tools/streams.anubis | 11 | read tools/streams.anubis |
| 12 | read system/string.anubis | 12 | read system/string.anubis |
src/main.anubis
| 1 | /************************************************* | 1 | /************************************************* |
| 2 | - * *Project* The Anubis Project | 2 | + * *Project* The HayamiKi (早見木) project |
| 3 | * | 3 | * |
| 4 | - * *Title* Database model manager | 4 | + * *Title* Interfacing, generating and controling a database with Anubis |
| 5 | * | 5 | * |
| 6 | - * *Copyright* Copyright © David René 2015. | 6 | + * *Copyright* Copyright © David René 2015-2016. |
| 7 | * | 7 | * |
| 8 | * | 8 | * |
| 9 | * | 9 | * |
| @@ -14,14 +14,21 @@ | @@ -14,14 +14,21 @@ | ||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | read tools/string.anubis | 16 | read tools/string.anubis |
| 17 | -read generation/files.anubis | ||
| 18 | -read calexium_lib/database/model/db_model.anubis | 17 | +read tools/basis.anubis |
| 18 | +//read generation/files.anubis | ||
| 19 | +read hayamiki_lib/hk_generator.anubis | ||
| 19 | read model.3.0.0.anubis | 20 | read model.3.0.0.anubis |
| 20 | 21 | ||
| 22 | + | ||
| 23 | + | ||
| 21 | global define One | 24 | global define One |
| 22 | hayamiki | 25 | hayamiki |
| 23 | ( | 26 | ( |
| 24 | List(String) args | 27 | List(String) args |
| 25 | - ) = | ||
| 26 | - generate_model_files(the_database_description). | 28 | + ) = |
| 29 | + if load_hk_generator is | ||
| 30 | + { | ||
| 31 | + failure then println("Hayamiki generator can't be load"), | ||
| 32 | + success(hk_gen) then forget(hk_gen.generate_model_files(the_database_description, "")) | ||
| 33 | + }. | ||
| 27 | 34 |
src/model.3.0.0.anubis
| 1 | +/* | ||
| 2 | + * Created by PyramIDE. | ||
| 3 | + * User: フランスのトトロ aka (David RENÉ) | ||
| 4 | + * Date: 13/02/2016 | ||
| 5 | + * Time: 10:39 | ||
| 6 | + * © Calexium | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +public define Int | ||
| 11 | + longest_table_name_size | ||
| 12 | + ( | ||
| 13 | + List(HK_App) apps, | ||
| 14 | + Int current_size | ||
| 15 | + )= | ||
| 16 | + if apps is | ||
| 17 | + { | ||
| 18 | + [] then current_size, | ||
| 19 | + [app . t_apps] then | ||
| 20 | + since app is hk_app(_, _, _, tables), | ||
| 21 | + with max_size = max(map((HK_Table table) |-> length(table.name), tables), current_size), | ||
| 22 | + longest_table_name_size(t_apps, max_size) | ||
| 23 | + }. | ||
| 24 | + | ||
| 25 | +define Int | ||
| 26 | + _max | ||
| 27 | + ( | ||
| 28 | + List(HK_Model_Column) columns, | ||
| 29 | + Int current_max | ||
| 30 | + )= | ||
| 31 | + if columns is | ||
| 32 | + { | ||
| 33 | + [] then current_max, | ||
| 34 | + [h . t] then | ||
| 35 | + since h is hk_column(name, _, _, _), | ||
| 36 | + _max(t, max(current_max, length(name))) | ||
| 37 | + } | ||
| 38 | + . | ||
| 39 | + | ||
| 40 | +public define Int | ||
| 41 | + max | ||
| 42 | + ( | ||
| 43 | + List(HK_Model_Column) columns | ||
| 44 | + )= | ||
| 45 | + _max(columns, 0). |