files.anubis 8.99 KB
/*
 * Created by PyramIDE.
 * User: フランスのトトロ 
 * Date: 31/12/2015
 * Time: 09:29
 * © Calexium 
 */

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/create_table.anubis
read generation/menu.anubis
read generation/fn_delete.anubis
read generation/choices_selector.anubis
read generation/vt_edit.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, show_string),
  since display   is hk_display(list_view, list_edit),
  
  with model = hk_model([hk_column("id", p_key, []). columns], 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_extract_web_arg(strm, table)    is { failure then failure, success(_) then
      if generate_extract_db_cursor(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(strm, table)            is { failure then failure, success(_) then
      if generate_get_one_with_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,
    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"+
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"
     ) 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,
    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_writer, so_far_delete, 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_writer, so_far_delete, dest_dir)
          
      },

    [table . t] then  
      since table is hk_table(name, _, _, _),
        with transmit = "transmit "+name+".anubis",
        with view = "vtm_view(\""+name+"\", get_viewable_"+name+")",
        with edit = "vtm_edit(\""+name+"\", get_editable_"+name+")",
        with writer = "tm_writer(\""+name+"\", update_"+name+")",
        with delete = "tm_delete(\""+name+"\", delete_"+name+")",
        _make_vtm(apps, t, [transmit . so_far_transmit], [view . so_far_view], [edit . so_far_edit], [writer . so_far_writer], [delete . so_far_delete], 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"),
  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(apps, destination_dir) is failure then println("failure");failure else
      println("Generating menu for Database "+name);
      if generate_menus(apps, destination_dir) is failure then println("failure");failure else
        writeString(ini, "DB_MODEL", "SHA1", current_db_SHA1);
        writeIniInfo(ini);
        success(unique)
  }.
  
   
global define HK_Generator_API
  hk_gen =
  hk_api(generate_model_files).