files.anubis 11.5 KB
/*
 * Created by PyramIDE.
 * User: フランスのトトロ aka (David RENÉ) 
 * Date: 31/12/2015
 * Time: 09:29
 * © David RENÉ
 */

read system/string.anubis
read system/files.anubis
read system/parameter/inifile.anubis

read hayamiki_lib/types/hayamiki.anubis
read hayamiki_lib/hk_generator.anubis

read tools/basis.anubis
read tools/streams.anubis
read tools/ISO-8601.anubis
read generation/header.anubis
read generation/types.anubis
read generation/densaku.anubis
read generation/extractor.anubis
read generation/create_table.anubis
read generation/hk_menu.anubis
read generation/cxm_lib_menu.anubis
read generation/fn_delete.anubis
read generation/choices_selector.anubis
read generation/vt_edit.anubis
read generation/vt_view.anubis
read generation/web_args.anubis
read generation/SQL_get_count.anubis
read generation/SQL_get_all.anubis
read check.anubis

define Maybe(One)
  generate_table
  (
    HK_Table  org_table,    //table to generate
    String    dest_dir,     //root directory of the generation
    Bool      use_densaku   //if true, this means the types are constructed by densaku for generating also the messages
  )
  =
  since org_table is hk_table(name, short_name, old_model, display),
  since old_model is hk_model(columns, constraints, show_string),
  since display   is hk_display(list_view, list_edit),
  
  with model = hk_model([hk_column("id", p_key, []). columns], constraints, show_string ),
  with table = hk_table(name, short_name, model, display),
  println("Generating file for table ["+name+"]");
  with file_name = dest_dir+"database/generated/"+name+".anubis",

  //create all necessary directories if doesn't exist.
  make_directories(file_name);
  
  if file(file_name, new) is
  {
    failure     then  println("can't create file "+file_name);failure,
    success(fd) then 
      with strm = make_stream(fd),
      if generate_header(strm, columns)                         is { failure then failure, success(_) then
      if generate_densaku_type(table, dest_dir, use_densaku)    is { failure then failure, success(_) then
      if generate_type(strm, table, use_densaku)                is { failure then failure, success(_) then
      if generate_get_default(strm, table)                      is { failure then failure, success(_) then
      if generate_columns_list(strm, table)                     is { failure then failure, success(_) then
      if generate_extract_web_arg_to_type(strm, table)          is { failure then failure, success(_) then
      if generate_extract_web_arg_to_update_field(strm, table)  is { failure then failure, success(_) then
      if generate_extract_db_cursor_to_mb_type(strm, table)     is { failure then failure, success(_) then
      if generate_extract_db_cursor_to_json(strm, table)        is { failure then failure, success(_) then      
      if generate_get_all(strm, table)                          is { failure then failure, success(_) then
      if generate_get_all_with_clause(strm, table)              is { failure then failure, success(_) then
      if generate_get_one_with_clause(strm, table)              is { failure then failure, success(_) then      
      if generate_get_one(strm, table)                          is { failure then failure, success(_) then
      if generate_get_one_json(strm, table)                     is { failure then failure, success(_) then
      //if generate_get_count_by_clause(strm, table)              is { failure then failure, success(_) then
      if generate_update(strm, table)                           is { failure then failure, success(_) then
      //if generate_delete(strm, table)                           is { failure then failure, success(_) then
      if generate_show_string(strm, table)                      is { failure then failure, success(_) then
      if generate_selector(strm, table)                         is { failure then failure, success(_) then
      if generate_choices_selector(strm, table)                 is { failure then failure, success(_) then
      if generate_VT_all_view(strm, table)                      is { failure then failure, success(_) then
      if generate_VT_all_edit(strm, table)                      is { failure then failure, success(_) then
      success(unique)}}}}}}}}}}}}}}}}}}}}
  }.
  
define One
  make_all_tables
  (
    List(HK_Table)  tables,   //list of the table model description
    String          dest_dir,
    Bool            use_densaku
  )
  =
  if tables is
  {
    []      then  println("Generation finished"),
    [h . t] then  
      if generate_table(h, dest_dir, use_densaku) is
      {
        failure     then println("Generation error")
        success(_)  then make_all_tables(t, dest_dir, use_densaku)
      }
  }.
  
define One
  make_all_tables
  (
    List(HK_App)  apps,
    String        dest_dir,
    Bool          use_densaku

  )=
  make_densaku_header(dest_dir, use_densaku);
  
  map_forget((HK_App app) |-> since app is hk_app(app_name, _, _, tables),
                       println("generating tables for App ["+app_name+"]");
                       make_all_tables(tables, dest_dir, use_densaku), apps);
                       
  close_densaku_file(dest_dir, use_densaku)
.

define Maybe(One)
  generate_vtm_file
  (
    List(String)    transmit,    
    List(String)    view,
    List(String)    edit,
//    List(String)    writer,
//    List(String)    delete,
    List(String)    controllers,
    String          dest_dir
  )=
  with file_name = dest_dir+"database/generated/vtm.anubis",
  if file(file_name, new) is
  {
    failure     then  println("can't create file "+file_name);failure,
    success(fd) then 
      if write_string(make_stream(fd),
"/*
 * Created by 早見木 (Hayamiki).
 * Database generator written by フランスのトトロ aka (David RENÉ)
 * Date: "+_Int_to_ISO_8601_date(now)+"
 * Time: "+_Int_to_ISO_8601_time(now)+"
 * 
 */
read tools/basis.anubis
read hayamiki_lib/view/view_table_manager_types.anubis\n
read hayamiki_lib/controller/hk_controller.anubis
read hayamiki_lib/controller/hk_sql_utils.anubis\n"+
join("\n", transmit)+"\n\n"+
"public define List(VTM_view)\n"+
"  generated_vtm_view_list =\n"+
"      [\n        "+join(",\n        ",view)+"\n"+
"      ].\n\n"+
"public define List(VTM_edit)\n"+
"  generated_vtm_edit_list =\n"+
"      [\n        "+join(",\n        ",edit)+"\n"+
"      ].\n\n"+
//"public define List(TM_writer)\n"+
//"  generated_tm_writer_list =\n"+
//"      [\n        "+join(",\n        ",writer)+"\n"+
//"      ].\n\n"+
//"public define List(TM_delete)\n"+
//"  generated_tm_delete_list =\n"+
//"      [\n        "+join(",\n        ",delete)+"\n"+
//"      ].\n\n"+
"public define List(HK_Table_controller)\n"+
"  generated_hk_table_controller_list =\n"+
"  [\n    "+join(",\n    ",controllers)+"\n"+
"  ]\n.\n\n"
     ) is                                                           //end of the function
  {
    failure     then  println("can't write vtm "); failure,
    success(_)  then  success(unique)
  }}.
  

 
define One
  _make_vtm
  (
    List(HK_App)    apps,             //list of application
    List(HK_Table)  tables,           //list of the table model description
    List(String)    so_far_transmit,    
    List(String)    so_far_view,
    List(String)    so_far_edit,
//    List(String)    so_far_writer,
//    List(String)    so_far_delete,
    List(String)    so_far_controllers,
    String          dest_dir
  )=
  if tables is
  {
    []          then
      if apps is 
      {
        []              then  forget(generate_vtm_file(so_far_transmit, so_far_view, so_far_edit, so_far_controllers, dest_dir));println("Generation finished"),
        [app . apps_t]  then
          _make_vtm(apps_t, app.hk_tables, so_far_transmit, so_far_view, so_far_edit, so_far_controllers, dest_dir)
          
      },

    [table . t] then  
      since table is hk_table(name, _, _, _),
        with transmit = "transmit "+name+".anubis",
        with view = "vtm_view(\""+name+"\", get_viewable_"+name+", get_all_"+name+"_view_name)",
        with edit = "vtm_edit(\""+name+"\", get_editable_"+name+")",
//        with writer = "tm_writer(\""+name+"\", update_"+name+"_from_type, update_"+name+"_from_fields)",
//        with delete = "tm_delete(\""+name+"\", delete_"+name+")",
        with controller = 
"hk_table_controller(\""+name+"\",
      //Column's name
      "+name+"_columns,
      "+name+"_select_fields,
      //Create
      update_"+name+"_from_type, 
      update_"+name+"_from_fields,
      //Read
      (SQLite3DataBase db, String clause) |-> get_count_by_clause(db, \""+name+"\", clause),
      make_"+name+"_json_extractor,
      get_one_"+name+"_to_json,
      get_all_"+name+"_by_clause_to_json,
      //Delete
      (SQLite3DataBase db, List(Int) ids) |-> delete_from_ids(db, \""+name+"\", ids),
      
      //view interface
      //selector
      get_selector_"+name+",
      hk_trigger_set(var([]), var([]), var([]), var([]), var([]), var([])) //initialize the triggers list as empty
    )",
   
        _make_vtm(apps, t, [transmit . so_far_transmit], [view . so_far_view], [edit . so_far_edit], [controller . so_far_controllers], dest_dir)
  }.
  
define One
  make_vtm
  (
    List(HK_App)  apps,  //list of the applications
    String        dest_dir
  )
  =
  _make_vtm(apps, [], [], [], [], [], dest_dir).
  
  
define Maybe(One)
  generate_model_files
  (
    HK_Database   db,             //database model description
    String        destination_dir,
    Bool          use_densaku
  )=
  //before processing the generation we check if we need to do it, by checking the SHA1 generated with the 
  //previous generation. If SHA1 is same, this means the database is exactly same and we have nothing to do.
  //This behaviour prevent to generate same database during automatic generation on compilation time.
  
  //process. We serialize the database model and make SHA1 of the result. This result is stored in file hayamiki.ini
  //in root of destination_dir
  
  println("\nHayamiki Generator");
  println("Destination dir: "+destination_dir);
  with ini = loadIniFile(destination_dir+"/hayamiki.ini"),
  
  with db_SHA1 = readString(ini, "DB_MODEL", "SHA1", "N/A"),
  with version = readString(ini, "DB_MODEL", "Version", "0.0.0.0"),
  with app_name= readString(ini, "DB_MODEL", "app_name", ""),
  println("Saved DB model SHA1 = "+db_SHA1);
  with current_db_SHA1 = to_ascii(sha1(serialize(db))),
  println("Current DB model SHA1 = "+current_db_SHA1);
  
  if db_SHA1 = current_db_SHA1 then
    success(println("Model already generated, nothing to do"))
  else if check_database(db) is 
  {
    failure           then println("Check database error");failure,
    success(database) then  
      since database is hk_database(name, apps),
      println("Generating models for Database "+name);
      make_all_tables(apps, destination_dir, use_densaku);
      println("Generating VTM for Database "+name);
      make_vtm(apps, destination_dir);
      println("Generating create for Database "+name);
      if generate_create_table(app_name, apps, destination_dir, version, current_db_SHA1) is failure then println("failure");failure else
      println("Generating menu for Database "+name);
      if generate_hk_menus(apps, destination_dir) is failure then println("failure");failure else
      if generate_cxm_lib_menus(apps, destination_dir) is failure then println("failure");failure else
        writeString(ini, "DB_MODEL", "SHA1", current_db_SHA1);
        writeString(ini, "DB_MODEL", "Version", version);        
        writeIniInfo(ini);
        sleep(3000);
        success(unique)
  }.
  
   
global define HK_Generator_API
  hk_gen_1_14 =
  hk_api(generate_model_files).