create_table.anubis 6.63 KB
/*
 * Created by PyramIDE.
 * User: フランスのトトロ aka (David RENÉ)
 * Date: 24/01/2016
 * Time: 18:13
 * © Calexium 
 */


read calexium_lib/database/model/db_model.anubis
read tools/basis.anubis
read tools/int.anubis
read system/string.anubis
read system/files.anubis
read tools/streams.anubis
read tools/ISO-8601.anubis

define String
  create_table_generate_one_column
  (
    HK_Model_Column column,
    Int             fill_size
  )=
  since column is hk_column(name, col_type, attributes, _),
  fill(name, fill_size)+ to_SQL_CREATE(col_type, attributes)
  .

define String
  create_table_generate_columns
  (
    List(HK_Model_Column) columns,
    String                indent
  )=
  //get the longest column name size, to be able to make formatting according to column name.
  with column_max_size = max(columns),
  join(",\n"+indent, map((HK_Model_Column column) |-> create_table_generate_one_column(column, column_max_size+1), columns))
  .

define String 
  create_table_generate_one_table
  (
    HK_Table  table
  )=
  since table is hk_table(name, short_name, model, display),
  since model is hk_model( columns, _),
  
  "\n"+
  "  // "+to_upper(name)+"\n"+
  "public define String create_table_"+name+" =\n"+
  "\"CREATE TABLE "+name+" (\n"+
  //columns
   "   "+create_table_generate_columns([hk_column("id",p_key) . columns], "   ")+
  "\n);\".\n"
  .

define String
  create_table_generate_all_tables
  (
    List(HK_App)    apps,     //
    List(HK_Table)  tables,   //list of the table model description
    String          so_far
  )=
  if tables is
  {
    []          then  //no more table to generate
      if apps is
      {
        []            then  //no more apps to generate
          so_far,           //return the all create table generated so far
        [app. t_apps] then  //another app available
          since app is hk_app(name, _, _, app_tables),
          create_table_generate_all_tables(t_apps, app_tables, so_far + "\n /************ TABLES for Application '"+name+"' ***************/")
      },

    [table . t] then  
      //generate the current table "CREATE TABLE"
      create_table_generate_all_tables(apps, t, so_far + create_table_generate_one_table(table))
  }.


  
define String
  generate_all_tables_list
  (
    List(HK_App)    apps,
//    List(HK_Table)  tables,  //list of the table model description
    String          indent
  )=
  //calculate then longest table name and add 4 for enclosed quote + coma + final space
  //hence we can make a beautiful formatting
  with max_space = longest_table_name_size(apps, 0) + 4,  
  join(",\n",
    map_append((HK_App  app)  |-> since app is hk_app(_, _, _, tables),
      map((HK_Table table)    |-> indent+"table("+fill("\""+table.name+"\",", max_space)+"create_table_"+table.name+")", tables), apps)).
  
public define Maybe(One)
  generate_create_table
  (
    List(HK_App)  apps  //list of the table model description
  )=
  //TODO manage version
  with version = "1.0.0.0",
   version_str = find_and_replace(version,".","_"), //replace the dot by underscore because dot is not allowed in function name by Anubis language
   
  with file_name        = "database/generated/migration/to_"+version+".anubis",
  with script_file_name = "database/generated/migration/to_"+version+"_scripts.anubis",
  
  //create all necessary directories if doesn't exist.
  make_directories(file_name);
  
  //create script file name as new file. Previous file with same name will be erased
  if file(script_file_name, new) is
  {
    failure             then  println("Can't create script "+script_file_name);failure,
    success(fd_script)  then
      with script_stream = make_stream(fd_script),
      //write into script file the generated create table
      if write_string(script_stream,
"/*
 * Created by 早見木 (Hayamiki).
 * Date: "+_Int_to_ISO_8601_date(now)+"
 * Time: "+_Int_to_ISO_8601_time(now)+"
 */
read data_base/sqlite_foreign_key.anubis
read data_base/db_types.anubis\n"+
  //call the generation of all tables
  create_table_generate_all_tables(apps, [], "")+
  //TODO make indexes
  "\npublic define List(String) db_indexes = [].\n"+
  "// ///////////////////////////////\n"+
  "// Foreign keys \n"+
  "public define List((String, String, String, String, FK_Null, FK_Cascade)) db_relations = [].\n"  
  ) is
  {
    failure     then println ("Can't generate script "+script_file_name);failure,
    success(_)  then
      //create file with create table management (alter_table, etc...)
      if file(file_name, new) is
      {
        failure     then  println("can't create file "+file_name);failure,
        success(fd) then 
      with stream = make_stream(fd),
  write_string(stream,
"/*
 * Created by 早見木 (Hayamiki).
 * Date: "+_Int_to_ISO_8601_date(now)+"
 * Time: "+_Int_to_ISO_8601_time(now)+"
 */
 * 
read tools/basis.anubis
read system/files.anubis
read system/logger.anubis
read data_base/db_tools.anubis

read calexium_lib/database/db_utils.anubis
read calexium_lib/database/migration_common_sqlite3.anubis
read calexium_lib/net_services_protocols/logger_service.anubis
read data_base/alter_table.anubis

read types/app_types.anubis
read app/app_constants.anubis
read app/app_loggers.anubis

read database/generated/migration/to_"+version+"_scripts.anubis

define String _version = \""+version+"\".

public define Maybe(One)
  create_v"+version_str+"_tables
  (
    SQLite3DataBase db,
    Logger          logger_debug
  )=
  if drop_all_triggers(db, logger_debug) is failure then failure else
  
  with tables = (List(DbTable)) [
"+generate_all_tables_list(apps, "                  ")+"
                ],
  if create_tables(db, logger_debug, tables, _version) is 
  {
    failure    then failure,
    success(_) then
      if make_foreign_keys(db, logger_debug, db_relations, _version) is failure then failure else
      success(unique)
  }.
           
public define Maybe(One)
  create_v"+version_str+"_indexes
  (
    SQLite3DataBase db,
    Logger          logger
  )=
  if create_indexes(db, logger, db_indexes, _version) is failure then failure else
  success(unique)
  .

define Maybe(One)
  to_v"+version_str+"_pre
  (
    SQLite3DataBase db,
    Logger          logger
  )=success(unique).

define Maybe(One)
  to_v"+version_str+"_post
  (
    SQLite3DataBase db,
    Logger          logger
  )=success(unique).

public define Maybe(One)
  migrate_to_v"+version_str+"
  (
    SQLite3DataBase db,
    Logger          logger,
  )=
  if to_v"+version_str+"_pre(db, logger)             is failure then failure
  else if create_v"+version_str+"_tables(db, logger) is failure then failure
  else if to_v"+version_str+"_post(db, logger)       is failure then failure
  else create_v"+version_str+"_indexes(db, logger).

  
  ")
  }}}
  .