src/query.c

00001 /* 
00002  * Copyright (C) 2005 Piotr Pokora <piotr.pokora@infoglob.pl>
00003  *
00004  * This program is free software; you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License as published
00006  * by the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #include <config.h>
00020 #include "midgard/midgard_schema.h"
00021 #include <glib/gprintf.h>
00022 #include "midgard/midgard_legacy.h"
00023 #include "midgard/midgard_object.h"
00024 #include "schema.h"
00025 #include "midgard/midgard_object_property.h"
00026 #include "midgard/midgard_reflection_property.h"
00027 #include "midgard_mysql.h"
00028 
00029 /* Define Default Query String */
00030 #define _DQS 512
00031 
00032 gint midgard_query_execute(midgard *mgd, gchar *sql, gpointer user_data)
00033 {
00034         g_assert(mgd->msql->mysql != NULL);
00035         
00036         g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "query=%s", sql);
00037         
00038         gint sq = mysql_query(mgd->msql->mysql, sql);
00039         g_free(sql);
00040         
00041         if (sq != 0) {
00042                 g_warning("query failed: %s", mysql_error(mgd->msql->mysql));
00043                 return -1;
00044         }
00045         return mysql_affected_rows(mgd->msql->mysql);         
00046 }
00047 
00048 GList *midgard_query_get_single_row(gchar *sql, MgdObject *object) 
00049 {
00050 
00051     g_assert(sql);
00052     g_assert(object);
00053     g_assert(object->mgd);
00054 
00055     midgard *mgd = object->mgd;
00056     GParamSpec *prop;
00057         
00058     g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "query=%s", sql);
00059     
00060     gint sq = mysql_query(mgd->msql->mysql, sql);
00061     g_free(sql);        
00062 
00063     if (sq != 0) {
00064         g_warning("query failed: %s", mysql_error(mgd->msql->mysql));
00065         return NULL;
00066     }
00067 
00068     guint retf, i;
00069     
00070     MYSQL_RES *results = mysql_store_result(mgd->msql->mysql);
00071     if (!results)
00072         return NULL;
00073     if ((retf = mysql_num_fields(results)) == 0) { 
00074         mysql_free_result(results);  
00075         return NULL;                                    
00076     }            
00077         
00078     MYSQL_ROW row = mysql_fetch_row(results);
00079     MYSQL_FIELD *field;
00080    
00081     if(!row){
00082             mysql_free_result(results);
00083             return NULL;
00084     }
00085     
00086     GList *list = NULL;
00087 
00088     for(i = 0; i < retf; i++){
00089     
00090         if (row[i] == NULL)
00091             row[i] = "";
00092 
00093         field = mysql_fetch_field_direct(results, i);
00094         prop = g_object_class_find_property(
00095                 (GObjectClass *)object->klass, field->name);
00096 
00097         if(prop != NULL) {
00098 
00099             switch (prop->value_type) {
00100 
00101                 /*
00102                 case G_TYPE_UINT:
00103                     list = g_list_prepend(list, GUINT_TO_POINTER(row[i]));
00104                     break;
00105                 */    
00106 
00107                 default:
00108                     list = g_list_prepend(list, g_strdup((gchar *)row[i]));
00109                     break;
00110             }
00111             
00112         } else {
00113             
00114             list = g_list_prepend(list, g_strdup((gchar *)row[i]));        
00115         }
00116     }
00117 
00118     list = g_list_reverse(list);
00119     mysql_free_result(results);
00120 
00121     return list;
00122     
00123 }
00124 
00125 gboolean midgard_object_set_from_query(gchar *sql, MgdObject *object) {
00126 
00127         g_assert(sql);
00128         g_assert(object);
00129         g_assert(object->mgd);
00130     
00131         midgard *mgd = object->mgd;
00132         GParamSpec *prop;
00133         GValue pval = {0,};     
00134 
00135         GString *nsql = g_string_new("");
00136         g_string_append(nsql, sql);
00137         g_string_append_printf(nsql, 
00138                         "AND %s.sitegroup IN (0, %d)",
00139                         midgard_object_class_get_table(MIDGARD_OBJECT_GET_CLASS(object)),
00140                         midgard_sitegroup_get_id(object->mgd)
00141                         );
00142 
00143     /* SG0 admin , select all */
00144     if (mgd_isroot(mgd)) 
00145         g_string_append(nsql, " AND 1=1");
00146     
00147     gchar *query = g_string_free(nsql, FALSE);
00148             
00149     g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "query=%s", query);
00150     
00151     gint sq = mysql_query(mgd->msql->mysql, query);
00152     g_free(query);
00153     g_free(sql);
00154 
00155     if (sq != 0) {
00156         g_warning("query failed: %s", mysql_error(mgd->msql->mysql));
00157         return FALSE;
00158     }
00159 
00160     guint ret_fields, i;
00161     
00162     MYSQL_RES *results = mysql_store_result(mgd->msql->mysql);
00163     
00164     if (!results)
00165         return FALSE;
00166     
00167     if ((ret_fields = mysql_num_fields(results)) == 0) {
00168         mysql_free_result(results);
00169         return FALSE;
00170     }
00171 
00172     if (mysql_num_rows(results) == 0) {
00173         
00174         mysql_free_result(results);
00175         return FALSE;
00176     }
00177     
00178 
00179     MYSQL_ROW row = mysql_fetch_row(results);
00180     MYSQL_FIELD *field;
00181     
00182     for(i = 0; i < ret_fields; i++){
00183         
00184         if (row[i] == NULL)
00185             row[i] = "";
00186         
00187         field = mysql_fetch_field_direct(results, i);
00188     
00189         if ((prop = g_object_class_find_property((GObjectClass *)object->klass, 
00190                                         field->name)) != NULL ) {
00191                 
00192                 g_value_init(&pval,prop->value_type);
00193                 
00194                 switch (prop->value_type) {
00195                         
00196                         case G_TYPE_STRING:
00197                                 g_value_set_string(&pval, (gchar *)row[i]);
00198                                 break;
00199                                 
00200                         case G_TYPE_UINT:
00201                                 g_value_set_uint(&pval, atoi(row[i]));
00202                                 break;
00203 
00204                         case G_TYPE_INT:
00205                                 g_value_set_int(&pval, atoi(row[i]));
00206                                 break;
00207                                 
00208                         case G_TYPE_CHAR:
00209                                 g_value_set_string(&pval, row[i]);
00210                                 break;
00211                                 
00212                         case G_TYPE_LONG:
00213                                 g_value_set_long(&pval, atol(row[i]));
00214                                 break;
00215                                 
00216                         case G_TYPE_FLOAT:
00217                                 g_value_set_float(&pval, g_ascii_strtod(row[i], NULL));
00218                                 break;
00219                                 
00220                         case G_TYPE_BOOLEAN:
00221                                 g_value_set_boolean(&pval, atoi(row[i]));
00222                                 break;
00223                                 
00224                         default:
00225                                 break;
00226                         }
00227                 g_object_set_property(G_OBJECT(object), field->name, &pval);
00228                 g_value_unset(&pval);
00229         }     
00230     }
00231    
00232     mysql_free_result(results);
00233     return TRUE;      
00234 }
00235 
00236 gboolean midgard_object_update_storage(MgdObject *object)
00237 {
00238         g_assert(object != NULL);
00239         
00240         MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS(object);
00241         const gchar *table = midgard_object_class_get_table(klass);
00242         const gchar *primary_property = 
00243                 midgard_object_class_get_primary_property(klass);
00244         if(table == NULL)
00245                 return FALSE;
00246 
00247         guint propn;
00248         gint i;
00249         GType prop_type;
00250         gchar **real_field = NULL;
00251         MgdSchemaPropertyAttr *prop_attr;
00252         GParamSpec **props = 
00253                 g_object_class_list_properties(
00254                                 G_OBJECT_CLASS(klass), &propn);
00255         MidgardReflectionProperty *mrp = 
00256                 midgard_reflection_property_new(klass);
00257 
00258         for(i = 0 ; i < propn; i++){
00259                 prop_type = 
00260                         midgard_reflection_property_get_midgard_type(
00261                                         mrp, props[i]->name);
00262                 prop_attr = g_hash_table_lookup(
00263                                 klass->data->prophash, props[i]->name);
00264                 /* Get table.column value from nick */
00265                 const gchar *nick =  g_param_spec_get_nick (props[i]);
00266                 if ((strlen(nick)) < 1) 
00267                         continue;
00268                 
00269                 real_field = g_strsplit(nick, ".", 2);
00270         
00271                 GString *alter_cmd = g_string_new("ALTER TABLE ");
00272                 g_string_append_printf(
00273                                 alter_cmd,
00274                                 " %s MODIFY ",
00275                                 real_field[0]);
00276 
00277                 /* dbtype attribute found , table altered with its value */
00278                 if((prop_attr != NULL) && (prop_attr->dbtype != NULL)) {
00279                         g_string_append_printf(
00280                                         alter_cmd, "%s %s ", 
00281                                         real_field[1],
00282                                         prop_attr->dbtype
00283                                         );
00284                 } else {
00285                         
00286                         if(prop_type == MGD_TYPE_STRING){
00287                                 g_string_append_printf(
00288                                                 alter_cmd,
00289                                                 "%s varchar(255) NOT NULL "
00290                                                 "default ''",
00291                                                 real_field[1]);
00292 
00293                         } else if(prop_type == MGD_TYPE_LONGTEXT){
00294                                 g_string_append_printf(
00295                                                 alter_cmd,
00296                                                 "%s longtext NOT NULL "
00297                                                 "default ''",
00298                                                 real_field[1]);
00299 
00300                         } else if(prop_type == MGD_TYPE_INT
00301                                         || prop_type ==  MGD_TYPE_UINT){
00302                                 g_string_append_printf(
00303                                                 alter_cmd,
00304                                                 "%s int(11) NOT NULL ",
00305                                                 real_field[1]);
00306                                 if(g_str_equal(props[i]->name, primary_property))
00307                                         g_string_append(alter_cmd,
00308                                                         "auto_increment");
00309                                 else 
00310                                         g_string_append(alter_cmd,
00311                                                         "default 0");
00312 
00313                         } else if(prop_type == MGD_TYPE_FLOAT) {
00314                                 g_string_append_printf(
00315                                                 alter_cmd,
00316                                                 "%s FLOAT NOT NULL "
00317                                                 "default '0.0000'",
00318                                                 real_field[1]);
00319 
00320                         } else if(prop_type == MGD_TYPE_BOOLEAN) {
00321                                 g_string_append_printf(
00322                                                 alter_cmd,
00323                                                 "%s BOOLEAN NOT NULL "
00324                                                 "default 0",
00325                                                 real_field[1]);
00326 
00327                         } else if(prop_type == MGD_TYPE_TIMESTAMP) {
00328                                 g_string_append_printf(
00329                                                 alter_cmd,
00330                                                 "%s datetime NOT NULL "
00331                                                 "default '0000-00-00 00:00:00'",
00332                                                 real_field[1]);
00333 
00334                         } else if(prop_type == MGD_TYPE_GUID){ 
00335                                 g_string_append_printf(
00336                                                 alter_cmd,
00337                                                 "%s varchar(80) NOT NULL "
00338                                                 "default ''",
00339                                                 real_field[1]);
00340                         } else {
00341                                 g_string_append_printf(
00342                                                 alter_cmd,
00343                                                 "%s varchar(255) NOT NULL "
00344                                                 "default ''",
00345                                                 real_field[1]);
00346                         }
00347                 }
00348                 
00349                 gint rv = midgard_query_execute(object->mgd, 
00350                                 g_string_free(alter_cmd, FALSE), NULL);
00351                 g_strfreev(real_field);
00352                 if(rv < 0){
00353                         g_free(props);
00354                         return FALSE;
00355                 }
00356         }
00357         g_free(props);
00358         
00359         return TRUE;
00360 }
00361 
00362 gboolean midgard_object_create_storage(MgdObject *object)
00363 {
00364         GString *cmd, *cmd_modify;
00365         MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS(object);
00366         const gchar *pfield = midgard_object_class_get_primary_field(klass);
00367         const gchar *primary_property = midgard_object_class_get_primary_property(klass);
00368         const gchar *table = midgard_object_class_get_table(klass);
00369         
00370         if(table == NULL)
00371                 return FALSE;
00372         
00373         GParamSpec *prop, **props;
00374         gint rv;
00375         guint propn, i = 0;
00376         gchar **real_field = NULL;
00377         const gchar *datatype;
00378         GType prop_type;
00379         
00380         /* CREATE TABLES and PRIMARY KEY */
00381         gchar **tables = g_strsplit(
00382                         midgard_object_class_get_tables(klass), ",", 0);
00383         
00384         do {            
00385                 cmd = g_string_new("CREATE TABLE IF NOT EXISTS ");
00386                 g_string_append(cmd, tables[i]);
00387                 
00388                 /* Get primary field used by object to define PRIMARY KEY in 
00389                  * newly created table. If no field is defined we use guid */
00390                 
00391                 g_string_append_printf(cmd , "(%s ", pfield);
00392                 
00393                 if ((prop = g_object_class_find_property(
00394                                                 G_OBJECT_CLASS(klass), 
00395                                                 primary_property)) != NULL ) {
00396 
00397                         switch (prop->value_type){                              
00398                                 case G_TYPE_STRING:
00399                                         g_string_append_printf(cmd , "varchar(80) NOT NULL");
00400                                         break;
00401                                 
00402                                 case G_TYPE_UINT:
00403                                         g_string_append_printf(cmd,
00404                                                         "int(%u) NOT NULL auto_increment", 11);
00405                         }
00406                 }
00407                 
00408                 g_string_append_printf(cmd , ", PRIMARY KEY(%s)) ", pfield);
00409                 rv = midgard_query_execute(object->mgd, g_string_free(cmd, FALSE), NULL);
00410                 
00411                 if (rv == -1){
00412                         g_warning("Table %s not created", table);
00413                         i++;
00414                         return FALSE;
00415                 } else {
00416                         g_message("Table '%s' OK", tables[i]);
00417                         i++;
00418                 }
00419                 
00420         } while (tables[i]);
00421         g_strfreev(tables);
00422  
00423     
00424         /* CREATE columns for properties */
00425         props = g_object_class_list_properties(
00426                         G_OBJECT_CLASS(object->klass), &propn);
00427         MidgardReflectionProperty *mrp =
00428                 midgard_reflection_property_new(klass);
00429         
00430         for(i = 0 ; i < propn; i++){
00431                 MgdSchemaPropertyAttr *prop_attr =
00432                         g_hash_table_lookup(klass->data->prophash, props[i]->name);
00433                 if(!prop_attr)
00434                         continue;
00435                 
00436                 /* Do not modify table if property is primary one */
00437                 if (g_ascii_strcasecmp(props[i]->name, prop->name) == 0)
00438                         continue;
00439                 
00440                 prop_type =
00441                         midgard_reflection_property_get_midgard_type(
00442                                         mrp, props[i]->name);
00443                 
00444                 const gchar *nick =  g_param_spec_get_nick (props[i]);
00445                 /* Property inherited from parent base midgard class, 
00446                  * do not create fields */
00447                 if ((strlen(nick)) < 1) 
00448                         continue;
00449 
00450                 /* Get table and field */
00451                 real_field = g_strsplit(nick, ".", 2);    
00452                 cmd = g_string_new("ALTER TABLE ");
00453                 g_string_append_printf(cmd, "%s ADD ", real_field[0]);        
00454                 datatype = prop_attr->dbtype;   
00455                 
00456                 if(datatype != NULL ) {
00457                         g_string_append_printf(cmd, 
00458                                         "%s %s "
00459                                         , real_field[1], datatype);
00460                 } else {
00461 
00462                         if(prop_type == MGD_TYPE_STRING){
00463                                 g_string_append_printf(
00464                                                 cmd,
00465                                                 "%s varchar(255) NOT NULL "
00466                                                 "default ''",
00467                                                 real_field[1]);
00468                                 
00469                         } else if(prop_type == MGD_TYPE_LONGTEXT){
00470                                 g_string_append_printf(
00471                                                 cmd,
00472                                                 "%s longtext NOT NULL "
00473                                                 "default ''",
00474                                                 real_field[1]);
00475                                 
00476                         } else if(prop_type == MGD_TYPE_INT
00477                                         || prop_type ==  MGD_TYPE_UINT){
00478                                 g_string_append_printf(
00479                                                 cmd,
00480                                                 "%s int(11) NOT NULL "
00481                                                 "default 0",
00482                                                 real_field[1]);
00483                                 
00484                         } else if(prop_type == MGD_TYPE_FLOAT) {
00485                                 g_string_append_printf(
00486                                                 cmd,
00487                                                 "%s FLOAT NOT NULL "
00488                                                 "default '0.0000'",
00489                                                 real_field[1]);
00490                                 
00491                         } else if(prop_type == MGD_TYPE_BOOLEAN) {
00492                                 g_string_append_printf(
00493                                                 cmd,
00494                                                 "%s BOOLEAN NOT NULL "
00495                                                 "default 0",
00496                                                 real_field[1]);
00497                         
00498                         } else if(prop_type == MGD_TYPE_TIMESTAMP) {
00499                                 g_string_append_printf(
00500                                                 cmd,
00501                                                 "%s datetime NOT NULL "
00502                                                 "default '0000-00-00 00:00:00'",
00503                                                 real_field[1]);
00504                                 
00505                         } else if(prop_type == MGD_TYPE_GUID){
00506                                 g_string_append_printf(
00507                                                 cmd,
00508                                                 "%s varchar(80) NOT NULL "
00509                                                 "default ''",
00510                                                 real_field[1]);
00511                         } else {
00512                                 g_string_append_printf(
00513                                                 cmd,
00514                                                 "%s varchar(255) NOT NULL "
00515                                                 "default ''",
00516                                                 real_field[1]);
00517                         }
00518                 }
00519                 rv = midgard_query_execute(
00520                                 object->mgd, g_string_free(cmd, FALSE), NULL);
00521                 g_message("Column '%s' OK", real_field[1]);     
00522                 g_strfreev(real_field);
00523         }
00524         g_free(props);
00525         
00526         /* Add guid column */
00527         cmd_modify = g_string_new("ALTER TABLE ");
00528         g_string_append_printf(cmd_modify,
00529                         "%s ADD guid varchar(80) NOT NULL",  table);
00530         rv = midgard_query_execute(object->mgd, g_string_free(cmd_modify, FALSE), NULL);        
00531         
00532         /* Add key for guid column */
00533         cmd_modify = g_string_new("ALTER TABLE ");
00534         g_string_append_printf(cmd_modify, "%s ADD KEY(guid)", table);
00535         rv = midgard_query_execute(object->mgd, g_string_free(cmd_modify, FALSE), NULL);
00536         
00537         /* Add sitegroup column */
00538         cmd_modify = g_string_new("ALTER TABLE ");
00539         g_string_append_printf(cmd_modify, 
00540                         "%s ADD sitegroup int(11) NOT NULL",  table);
00541         rv = midgard_query_execute(object->mgd, g_string_free(cmd_modify, FALSE), NULL);
00542                 
00543         /* Add key for sitegroup column */       
00544         cmd_modify = g_string_new("ALTER TABLE ");
00545         g_string_append_printf(cmd_modify, "%s ADD KEY(sitegroup)",  table);
00546         rv = midgard_query_execute(object->mgd, g_string_free(cmd_modify, FALSE), NULL);
00547 
00548         /* Add key for parent and up columns */
00549         if (midgard_object_class_get_parent_property(klass)) {
00550                 cmd_modify = g_string_new("ALTER TABLE ");
00551                 g_string_append_printf(cmd_modify, "%s ADD KEY(%s)", 
00552                                 table, midgard_object_class_get_parent_property(klass));
00553                 rv = midgard_query_execute(object->mgd, g_string_free(cmd_modify, FALSE), NULL); 
00554         }
00555         
00556         if (midgard_object_class_get_up_property(klass)) {
00557                 cmd_modify = g_string_new("ALTER TABLE ");
00558                 g_string_append_printf(cmd_modify, "%s ADD KEY(%s)",
00559                                 table, midgard_object_class_get_up_property(klass));
00560                 rv = midgard_query_execute(object->mgd, g_string_free(cmd_modify, FALSE), NULL);
00561         }
00562         
00563         /* Add metadata columns */
00564         /* FIXME , change this when MIDGARD_TYPE_TIMESTAMP is fully supported */
00565         
00566         guint metapropn;
00567         props = g_object_class_list_properties(
00568                         G_OBJECT_GET_CLASS(object->metadata), &metapropn);
00569         const gchar *meta_field;        
00570         for(i = 0 ; i < metapropn; i++){
00571                 
00572                 meta_field =  g_param_spec_get_nick (props[i]);
00573                 
00574                 if(g_str_equal(props[i]->name, "creator") ||
00575                                 g_str_equal(props[i]->name, "revisor") ||
00576                                 g_str_equal(props[i]->name, "approver") ||
00577                                 g_str_equal(props[i]->name, "locker") ||
00578                                 g_str_equal(props[i]->name, "owner")) {
00579                         cmd = g_string_new("ALTER table ");
00580                         g_string_append_printf(cmd, 
00581                                         "%s ADD (%s "
00582                                         "varchar(80) NOT NULL default '')",
00583                                         table, meta_field);
00584                         midgard_query_execute(object->mgd, 
00585                                         g_string_free(cmd, FALSE), NULL);
00586                 }
00587                 
00588                 if(g_str_equal(props[i]->name, "authors")) {
00589                         cmd = g_string_new("ALTER table ");
00590                         g_string_append_printf(cmd, 
00591                                         "%s ADD (%s "
00592                                         "longtext NOT NULL default '')",
00593                                         table, meta_field);
00594                         midgard_query_execute(object->mgd, 
00595                                         g_string_free(cmd, FALSE), NULL);
00596                 }
00597                 
00598                 if(g_str_equal(props[i]->name, "created") ||
00599                                 g_str_equal(props[i]->name, "revised") ||
00600                                 g_str_equal(props[i]->name, "approved") ||
00601                                 g_str_equal(props[i]->name, "locked") ||
00602                                 g_str_equal(props[i]->name, "schedulestart") ||
00603                                 g_str_equal(props[i]->name, "scheduleend") ||
00604                                 g_str_equal(props[i]->name, "published") ||
00605                                 g_str_equal(props[i]->name, "exported") ||
00606                                 g_str_equal(props[i]->name, "imported")) { 
00607                         cmd = g_string_new("ALTER table ");
00608                         g_string_append_printf(cmd,
00609                                         "%s ADD (%s "
00610                                         "datetime NOT NULL default '0000-00-00 00:00:00')",
00611                                         table, meta_field);
00612                         midgard_query_execute(object->mgd, 
00613                                         g_string_free(cmd, FALSE), NULL);
00614                 }
00615                 
00616                 if(g_str_equal(props[i]->name, "hidden") ||
00617                                 g_str_equal(props[i]->name, "navnoentry") ||
00618                                 g_str_equal(props[i]->name, "deleted")) {                       
00619                         cmd = g_string_new("ALTER table ");
00620                         g_string_append_printf(cmd,
00621                                         "%s ADD (%s "
00622                                         "BOOL default 0)",
00623                                         table, meta_field);
00624                         midgard_query_execute(object->mgd,
00625                                         g_string_free(cmd, FALSE), NULL);
00626                 }
00627                 
00628                 if(g_str_equal(props[i]->name, "size") ||
00629                                 g_str_equal(props[i]->name, "revision") ||
00630                                 g_str_equal(props[i]->name, "score")) {
00631                         cmd = g_string_new("ALTER table ");
00632                         g_string_append_printf(cmd,
00633                                         "%s ADD (%s "
00634                                         "int(11) NOT NULL default '0')",
00635                                         table, meta_field);
00636                         midgard_query_execute(object->mgd,
00637                                         g_string_free(cmd, FALSE), NULL);
00638                 }
00639         }   
00640         g_free(props);
00641         
00642         /* g_fprintf(stderr, "."); */
00643         g_message("Table and columns for '%s' OK", object->cname);
00644         return TRUE;   
00645 }

Generated on Thu Feb 22 06:15:18 2007 for midgard-core by  doxygen 1.4.6