sql_dbcreator.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:12k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * This program is free software; you can redistribute it and/or
  3.  * modify it under the terms of the GNU General Public License
  4.  * as published by the Free Software Foundation; either version 2
  5.  * of the License, or (at your option) any later version.
  6.  *
  7.  * This program is distributed in the hope that it will be useful,
  8.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  * GNU General Public License for more details.
  11.  *
  12.  * You should have received a copy of the GNU General Public License
  13.  * along with this program; if not, write to the Free Software
  14.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  15.  */
  16. #ifdef WITH_SQL
  17. #include "common/setup_before.h"
  18. #include <stdio.h>
  19. #ifdef STDC_HEADERS
  20. # include <stdlib.h>
  21. #else
  22. # ifdef HAVE_MALLOC_H
  23. #  include <malloc.h>
  24. # endif
  25. #endif
  26. #ifdef HAVE_STRING_H
  27. # include <string.h>
  28. #else
  29. # ifdef HAVE_STRINGS_H
  30. #  include <strings.h>
  31. # endif
  32. #endif
  33. #define  SQL_DBCREATOR_INTERNAL_ACCESS
  34. #include "sql_dbcreator.h"
  35. #undef   SQL_DBCREATOR_INTERNAL_ACCESS
  36. #include "storage_sql.h"
  37. #include "common/eventlog.h"
  38. #include "common/util.h"
  39. #include "compat/strdup.h"
  40. #include "common/list.h"
  41. #include "prefs.h"
  42. #include "common/setup_after.h"
  43. t_elem  * curr_table  = NULL;
  44. t_elem  * curr_column = NULL;
  45. t_db_layout * db_layout;
  46. t_column * create_column(char * name, char * value)
  47. {
  48.   t_column * column;
  49.   
  50.   if (!(name))
  51.     {
  52.       eventlog(eventlog_level_error,__FUNCTION__,"got NULL column name");
  53.       return NULL;
  54.     }
  55.   
  56.   if (!(value))
  57.     {
  58.       eventlog(eventlog_level_error,__FUNCTION__,"got NULL column value");
  59.       return NULL;
  60.     }
  61.   
  62.   if (!(column = malloc(sizeof(t_column))))
  63.     {
  64.       eventlog(eventlog_level_error,__FUNCTION__,"could not alloc mem for column");
  65.       return NULL;
  66.     }
  67.   
  68.   if (!(column->name  = strdup(name)))
  69.     {
  70.       eventlog(eventlog_level_error,__FUNCTION__,"could not strdup column name");
  71.       free((void *)column);
  72.       return NULL;
  73.     }
  74.   
  75.   if (!(column->value = strdup(value)))
  76.     {
  77.       eventlog(eventlog_level_error,__FUNCTION__,"could not strdup column value");
  78.       free((void *)column->name);
  79.       free((void *)column);
  80.       return NULL;
  81.     }
  82.   
  83.   return column;
  84. };
  85. void dispose_column(t_column * column)
  86. {
  87.   if (column)
  88.     {
  89.       if (column->name)  free((void *)column->name);
  90.       if (column->value) free((void *)column->value);
  91.       free((void *)column);
  92.     }
  93. }
  94. t_table * create_table(char * name)
  95. {
  96.   t_table * table;
  97.   
  98.   if (!(name))
  99.     {
  100.       eventlog(eventlog_level_error,__FUNCTION__,"got NULL table name");
  101.       return NULL;
  102.     }
  103.   
  104.   if (!(table = malloc(sizeof(t_table))))
  105.     {
  106.       eventlog(eventlog_level_error,__FUNCTION__,"could not alloc mem for table");
  107.       return NULL;
  108.     }
  109.   
  110.   if (!(table->name = strdup(name)))
  111.     {
  112.       eventlog(eventlog_level_error,__FUNCTION__,"could not strdup table name");
  113.       free((void *)table);
  114.     }
  115.   
  116.   if (!(table->columns = list_create()))
  117.     {
  118.       eventlog(eventlog_level_error,__FUNCTION__,"could not create list");
  119.       free((void *)table->name);
  120.       free((void *)table);
  121.     }
  122.   
  123.   return table;
  124. }
  125. void dispose_table(t_table * table)
  126. {
  127.   t_elem * curr;
  128.   t_column * column;
  129.   
  130.   if (table)
  131.     {
  132.       if (table->name) free((void *)table->name);
  133.       // free list
  134.       if (table->columns)
  135.         {
  136.           LIST_TRAVERSE(table->columns,curr)
  137.     {
  138.       if (!(column = elem_get_data(curr)))
  139. {
  140.   eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
  141.   continue;
  142. }
  143.       dispose_column(column);
  144.       list_remove_elem(table->columns,curr);
  145.     }
  146.   
  147.   list_destroy(table->columns);
  148.   
  149.         }
  150.       
  151.       free((void *)table);
  152.     }
  153. }
  154. void table_add_column(t_table * table, t_column * column)
  155. {
  156.   if ((table) && (column))
  157.     {
  158.       if (list_append_data(table->columns,column)<0)
  159.         {
  160.           eventlog(eventlog_level_error,__FUNCTION__,"failed to add column");
  161.           dispose_column(column);
  162.         }
  163.     }
  164. }
  165. t_db_layout * create_db_layout()
  166. {
  167.   t_db_layout * db_layout;
  168.   
  169.   if (!(db_layout = malloc(sizeof(t_db_layout))))
  170.     {
  171.       eventlog(eventlog_level_error,__FUNCTION__,"could not alloc mem for db_layout");
  172.       return NULL;
  173.     }
  174.   
  175.   if (!(db_layout->tables = list_create()))
  176.     {
  177.       eventlog(eventlog_level_error,__FUNCTION__,"could not create list");
  178.       free((void *)db_layout);
  179.       return NULL;
  180.     }
  181.   
  182.   return db_layout;
  183. }
  184. void dispose_db_layout(t_db_layout * db_layout)
  185. {
  186.   t_elem  * curr;
  187.   t_table * table;
  188.  
  189.   if (db_layout)
  190.     {
  191.       if (db_layout->tables)
  192.         {
  193.           LIST_TRAVERSE(db_layout->tables,curr)
  194.     {
  195.       if (!(table = elem_get_data(curr)))
  196. {
  197.   eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
  198.   continue;
  199. }
  200.       dispose_table(table);
  201.       list_remove_elem(db_layout->tables,curr);
  202.     }
  203.           list_destroy(db_layout->tables);
  204.         }
  205.       free((void *)db_layout);
  206.     }
  207.   
  208. }
  209. void db_layout_add_table(t_db_layout * db_layout, t_table * table)
  210. {
  211.   if ((db_layout) && (table))
  212.     {
  213.       if (list_append_data(db_layout->tables,table)<0)
  214.         {
  215.           eventlog(eventlog_level_error,__FUNCTION__,"failed to add table");
  216.           dispose_table(table);
  217.         }
  218.     }
  219. }
  220. t_table * db_layout_get_first_table(t_db_layout * db_layout)
  221. {
  222.   t_table * table;
  223.   curr_column = NULL;
  224.   if (!(db_layout))
  225.   {
  226.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL db_layout");
  227.     return NULL;
  228.   }
  229.   if (!(db_layout->tables))
  230.   {
  231.     eventlog(eventlog_level_error,__FUNCTION__,"found NULL db_layout->tables");
  232.     return NULL;
  233.   }
  234.   if (!(curr_table = list_get_first(db_layout->tables)))
  235.   {
  236.     eventlog(eventlog_level_error,__FUNCTION__,"db_layout has no tables");
  237.     return NULL;
  238.   }
  239.   if (!(table = elem_get_data(curr_table)))
  240.   {
  241.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL elem in list");
  242.     return NULL;
  243.   }
  244.   return table;
  245. }
  246. t_table * db_layout_get_next_table()
  247. {
  248.   t_table * table;
  249.   curr_column = NULL;
  250.   if (!(curr_table))
  251.   {
  252.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL curr_table");
  253.     return NULL;
  254.   }
  255.   if (!(curr_table = elem_get_next(curr_table))) return NULL;
  256.   if (!(table = elem_get_data(curr_table)))
  257.   {
  258.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL elem in list");
  259.     return NULL;
  260.   }
  261.   return table;
  262. }
  263. t_column * table_get_first_column(t_table * table)
  264. {
  265.   t_column * column;
  266.   if (!(table))
  267.   {
  268.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL table");
  269.     return NULL;
  270.   }
  271.   if (!(table->columns))
  272.   {
  273.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL table->columns");
  274.     return NULL;
  275.   }
  276.   if (!(curr_column = list_get_first(table->columns)))
  277.   {
  278.     eventlog(eventlog_level_error,__FUNCTION__,"table has no columns");
  279.     return NULL;
  280.   }
  281.   if (!(column = elem_get_data(curr_column)))
  282.   {
  283.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL elem in list");
  284.     return NULL;
  285.   }
  286.   return column;
  287. }
  288. t_column * table_get_next_column()
  289. {
  290.   t_column * column;
  291.   if (!(curr_column))
  292.   {
  293.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL curr_column");
  294.     return NULL;
  295.   }
  296.   if (!(curr_column = elem_get_next(curr_column))) return NULL;
  297.   if (!(column = elem_get_data(curr_column)))
  298.   {
  299.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL elem in list");
  300.     return NULL;
  301.   }
  302.   return column;
  303. }
  304. int load_db_layout(char const * filename)
  305. {
  306.   FILE * fp;
  307.   int    lineno;
  308.   char * line        = NULL;
  309.   char * tmp         = NULL;
  310.   char * table       = NULL;
  311.   char * column      = NULL;
  312.   char * value       = NULL;
  313.   t_table * _table   = NULL;
  314.   t_column * _column = NULL;
  315.   if (!(filename))
  316.   {
  317.     eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
  318.     return -1;
  319.   }
  320.   if (!(fp = fopen(filename,"r")))
  321.   {
  322.     eventlog(eventlog_level_error,__FUNCTION__,"can't open sql_DB_layout file");
  323.     return -1;
  324.   }
  325.   if (!(db_layout = create_db_layout()))
  326.   {
  327.     eventlog(eventlog_level_error,__FUNCTION__,"failed to create db_layout");
  328.     fclose(fp);
  329.     return -1;
  330.   }
  331.   for (lineno=1; (line = file_get_line(fp)) ; lineno++)
  332.   {
  333.     switch (line[0])
  334.     {
  335.       case '[':
  336.         table = &line[1];
  337.         if (!(tmp = strchr(table,']')))
  338.         {
  339.           eventlog(eventlog_level_error,__FUNCTION__,"missing ']' in line %i",lineno);
  340.           free((void *)line);
  341.           continue;
  342.         }
  343.         tmp[0]='';
  344.         if (_table)  db_layout_add_table(db_layout,_table);
  345.         _table = create_table(table);
  346.         break;
  347.       case '"':
  348.         if (!(_table))
  349.         {
  350.           eventlog(eventlog_level_error,__FUNCTION__,"found a column without previous table in line %i",lineno);
  351.           free((void *)line);
  352.           continue;
  353.         }
  354.         column = &line[1];
  355.         if (!(tmp = strchr(column,'"')))
  356.         {
  357.           eventlog(eventlog_level_error,__FUNCTION__,"missing '"' at the end of column definitioni in line %i",lineno);
  358.           free((void *)line);
  359.           continue;
  360.         }
  361.         tmp[0]='';
  362.         tmp++;
  363.         if (!(tmp = strchr(tmp,'"')))
  364.         {
  365.           eventlog(eventlog_level_error,__FUNCTION__,"missing default value in line %i",lineno);
  366.           free((void *)line);
  367.           continue;
  368.         }
  369.         value = ++tmp;
  370.         if (!(tmp = strchr(value,'"')))
  371.         {
  372.           eventlog(eventlog_level_error,__FUNCTION__,"missing '"' at the end of default value in line %i",lineno);
  373.           free((void *)line);
  374.           continue;
  375.         }
  376.         tmp[0]='';
  377.         _column = create_column(column,value);
  378.         table_add_column(_table,_column);
  379.         _column = NULL;
  380.         break;
  381.       case '#':
  382.         break;
  383.       default:
  384.         eventlog(eventlog_level_error,__FUNCTION__,"illegal starting symbol at line %i",lineno);
  385.     }
  386.     free((void *)line);
  387.   }
  388.   if (_table) db_layout_add_table(db_layout,_table);
  389.   fclose(fp);
  390.   return 0;
  391. }
  392. int sql_dbcreator(t_sql_engine * sql)
  393. {
  394.   t_table     * table;
  395.   t_column    * column;
  396.   char        _column[1024];
  397.   char        query[1024];
  398.   load_db_layout(prefs_get_DBlayoutfile());
  399.   eventlog(eventlog_level_info, __FUNCTION__,"Creating missing tables and columns (if any)");
  400.  
  401.   for (table = db_layout_get_first_table(db_layout);table;table = db_layout_get_next_table())
  402.   {
  403.      column = table_get_first_column(table);
  404.      sprintf(query,"CREATE TABLE %s (%s default %s)",table->name,column->name,column->value); 
  405.      //create table if missing
  406.      if (!(sql->query(query)))
  407.      {
  408.        eventlog(eventlog_level_info,__FUNCTION__,"added missing table %s to DB",table->name);
  409.        eventlog(eventlog_level_info,__FUNCTION__,"added missing column %s to table %s",column->name,table->name);
  410.      }
  411.     for (;column;column = table_get_next_column())
  412.     {
  413.       sprintf(query,"ALTER TABLE %s ADD %s",table->name,column->name);
  414.       // add missing columns
  415.       if (!(sql->query(query)))
  416.       {
  417.         eventlog(eventlog_level_info,__FUNCTION__,"added missing column %s to table %s",column->name,table->name);
  418. sscanf(column->name,"%s",_column); //get column name without format infos
  419. sprintf(query,"ALTER TABLE %s ALTER %s SET DEFAULT %s",table->name,_column,column->value);
  420. sql->query(query);
  421.       }
  422.     }
  423.     column = table_get_first_column(table);
  424.     sscanf(column->name,"%s",_column); //get column name without format infos
  425.     sprintf(query,"INSERT INTO %s (%s) VALUES (%s)",table->name,_column,column->value);
  426.     if (!(sql->query(query)))
  427.     {
  428.       eventlog(eventlog_level_info,__FUNCTION__,"added missing default account to table %s",table->name);
  429.     }
  430.   }
  431.   
  432.   dispose_db_layout(db_layout);
  433.  
  434.   eventlog(eventlog_level_info,__FUNCTION__,"finished adding missing tables and columns");  
  435.   return 0;
  436. }
  437. #endif /* WITH_SQL */