Changeset 22248

Show
Ignore:
Timestamp:
05/20/09 13:42:27 (1 year ago)
Author:
piotras
Message:

Copy and extend MgdSchema?. Fixes #790, refs #1008

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/midgard/core/midgard/Makefile.am

    r22077 r22248  
    125125        src/midgard_core_config.h \ 
    126126        src/midgard_core_object_parameter.h \ 
     127        src/midgard_core_schema.c \ 
     128        src/midgard_core_xml.h \ 
     129        src/midgard_core_xml.c \ 
    127130        src/midgard_dbus.h \ 
    128131        src/midgard_dbus.c \ 
  • trunk/midgard/core/midgard/src/mgdschema.c

    r22218 r22248  
    11/* Midgard schema , records and objects definition. 
    22    
    3   Copyright (C) 2004,2005,2006,2007,2008 Piotr Pokora <piotrek.pokora@gmail.com> 
     3  Copyright (C) 2004,2005,2006,2007,2008, 2009 Piotr Pokora <piotrek.pokora@gmail.com> 
    44   
    55  This program is free software; you can redistribute it and/or modify it 
     
    3232#include <libxml/parserInternals.h> 
    3333#include "guid.h" 
     34#include "midgard_core_xml.h" 
    3435 
    3536/* TODO tune header files , no need to include string.h while we need to include midgard.h in almost every case */ 
     
    4546static const gchar *parsed_schema = NULL; 
    4647 
    47 /* prototypes */  
    48 static void _copy_schemas(gpointer key, gpointer value, gpointer userdata); 
    49  
    50 MgdSchemaPropertyAttr *_mgd_schema_property_attr_new(){ 
    51          
    52         MgdSchemaPropertyAttr *prop = g_new(MgdSchemaPropertyAttr, 1); /* FIXME, LEAK */ 
    53         prop->gtype = G_TYPE_NONE; 
    54         prop->type = NULL; 
    55         prop->default_value = NULL; 
    56         prop->dbtype = NULL; 
    57         prop->field = NULL; 
    58         prop->dbindex = FALSE; 
    59         prop->table = NULL; 
    60         prop->tablefield = NULL; 
    61         prop->upfield = NULL; 
    62         prop->parentfield = NULL; 
    63         prop->primaryfield = NULL; 
    64         prop->is_multilang = FALSE; 
    65         prop->link = NULL; 
    66         prop->link_target = NULL; 
    67         prop->is_primary = FALSE; 
    68         prop->is_reversed = FALSE; 
    69         prop->is_link = FALSE; 
    70         prop->is_linked = FALSE; 
    71         prop->description = NULL; 
    72          
    73         return prop;  
    74 } 
    75  
    76 void _mgd_schema_property_attr_free(MgdSchemaPropertyAttr *prop) 
    77 { 
    78         g_assert(prop != NULL); 
    79  
    80         g_free((gchar *)prop->type); 
    81         g_free((gchar *)prop->dbtype);   
    82         g_free((gchar *)prop->field); 
    83         g_free((gchar *)prop->table); 
    84         g_free((gchar *)prop->tablefield); 
    85         g_free((gchar *)prop->upfield); 
    86         g_free((gchar *)prop->parentfield); 
    87         g_free((gchar *)prop->primaryfield); 
    88         g_free((gchar *)prop->link); 
    89         g_free((gchar *)prop->link_target); 
    90  
    91         g_free(prop); 
    92 } 
    93  
    9448void _destroy_property_hash(gpointer key, gpointer value, gpointer userdata) 
    9549{ 
     
    11367{ 
    11468        MgdSchemaTypeAttr *type = g_new(MgdSchemaTypeAttr, 1); 
     69        type->name = NULL; 
    11570        type->base_index = 0; 
    11671        type->num_properties = 0; 
     
    13186        type->tableshash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); 
    13287        type->prophash = g_hash_table_new(g_str_hash, g_str_equal); 
    133         type->childs = NULL; 
     88        type->children = NULL; 
    13489        type->unique_name = NULL; 
    13590        type->sql_select_full = NULL; 
    136         type->tmp_select = NULL; 
     91        type->copy_from = NULL; 
     92        type->extends = NULL; 
    13793         
    13894        return type; 
     
    14298{ 
    14399        g_assert(type != NULL); 
     100 
     101        g_free(type->name); 
     102        type->name = NULL; 
    144103 
    145104        g_free((gchar *)type->table); 
     
    155114        g_hash_table_destroy(type->prophash); 
    156115 
    157         g_free(type->tmp_select); 
    158116        g_free(type->sql_select_full); 
    159117        g_free(type->parentfield); 
     
    217175 * We change them only here , and in xml file itself. 
    218176 */ 
    219 static const gchar *mgd_complextype[] = { "type", "property", "Schema", "description", "include", NULL }; 
     177static const gchar *mgd_complextype[] = { "type", "property", "Schema", "description", "include", "copy", "extends", NULL }; 
    220178static const gchar *mgd_attribute[] = {  
    221         "name",  
    222         "table",  
     179        TYPE_RW_TYPE, 
     180        TYPE_RW_NAME,  
     181        TYPE_RW_TABLE,  
     182        TYPE_RW_EXTENDS, 
     183        TYPE_RW_COPY, 
    223184        "parent",  
    224185        "parentfield",  
    225         "type",  
    226186        "link",  
    227187        "upfield",  
     
    310270/* Get all type attributes */ 
    311271static void 
    312 _get_type_attributes(xmlNode * node, MgdSchemaTypeAttr *type_attr
     272_get_type_attributes(xmlNode * node, MgdSchemaTypeAttr *type_attr, MidgardSchema *schema
    313273{ 
    314274        xmlAttr *attr; 
     
    322282                while (attr != NULL){ 
    323283 
    324                         if(!strv_contains(mgd_attribute, attr->name)){ 
     284                        if (!strv_contains(mgd_attribute, attr->name)){ 
    325285                                g_warning("Wrong attribute '%s' in '%s' on line %ld", 
    326286                                                attr->name, parsed_schema, xmlGetLineNo(node));  
    327287                        }        
    328                         attrval = xmlNodeListGetString (node->doc, attr->children, 1); 
    329                                          
    330                         if(g_str_equal(attr->name, "table")) { 
    331                                 /* Check if table name is reserved one */ 
    332                                 if (strv_contains(rtables, attrval)) { 
    333                                         g_critical("'%s' is reserved table name", 
    334                                                         attrval); 
    335                                 }                                                                
    336                                 type_attr->table = g_strdup((const gchar *)attrval);                                                    } 
    337  
    338                         if(g_str_equal(attr->name, "parent")) 
    339                                 type_attr->parent = g_strdup((gchar *)attrval); 
    340          
     288 
     289                        attr = attr->next; 
     290                }        
     291 
     292                /* Get table name */ 
     293                attrval = xmlGetProp(node, (const xmlChar *)TYPE_RW_TABLE); 
     294                if (attrval) { 
     295 
     296                        if (strv_contains(rtables, attrval))  
     297                                g_error("'%s' is reserved table name", attrval);                                         
     298 
     299                        midgard_core_schema_type_set_table (type_attr, (const gchar *)attrval);                          
     300                        xmlFree(attrval);        
     301                } 
     302 
     303                /* parent */ 
     304                attrval = xmlGetProp(node, (const xmlChar *)TYPE_RW_PARENT); 
     305                if (attrval) { 
     306                 
     307                        if (type_attr->parent) g_free((gchar *)type_attr->parent);       
     308                        type_attr->parent = g_strdup((gchar *)attrval); 
    341309                        xmlFree(attrval); 
    342                         attr = attr->next;                       
     310                } 
     311 
     312                /* extends */ 
     313                attrval = xmlGetProp(node, (const xmlChar *)TYPE_RW_EXTENDS); 
     314                if (attrval) {  
     315 
     316                        type_attr->extends = g_strdup((gchar *)attrval); 
     317                        xmlChar *table_name = (xmlChar *)xmlGetProp(node, (const xmlChar *)"table");     
     318 
     319                        if (table_name != NULL) { 
     320 
     321                                __warn_msg(node, "Can not define 'table' and 'extends' attributes together"); 
     322                                xmlFree(table_name); 
     323 
     324                                /* This might be undefined result, so we fallback to NULL default */ 
     325                                g_free(type_attr->extends); 
     326                                type_attr->extends = NULL; 
     327                        } 
     328         
     329                        xmlFree(table_name); 
     330                } 
     331 
     332                /* copy */ 
     333                attrval = xmlGetProp(node, (const xmlChar *)TYPE_RW_COPY); 
     334                if (attrval) { 
     335 
     336                        type_attr->copy_from = g_strdup((gchar *)attrval); 
     337                        xmlChar *table_name = (xmlChar *)xmlGetProp(node, (const xmlChar *)"table");     
     338 
     339                        if (table_name == NULL) { 
     340 
     341                                __warn_msg(node, "Can not copy MgdSchema type without storage defined"); 
     342                                g_error("Table definition missed"); 
     343                        } 
     344         
     345                        xmlFree(table_name); 
     346                        xmlFree(attrval); 
    343347                } 
    344348        } 
     
    348352                MgdSchemaTypeAttr *type_attr, MgdSchemaPropertyAttr *prop_attr) 
    349353{ 
    350         gboolean typeisset = FALSE; 
    351354        xmlAttr *attr; 
    352355        xmlChar *attrval; 
     
    363366                                attrval = xmlNodeListGetString (node->doc, attr->children, 1); 
    364367 
    365                                 if (strv_contains(schema_allowed_types, attrval)) { 
    366                                          
    367                                         typeisset = TRUE; 
    368                                          
    369                                         prop_attr->type = g_strdup((const gchar*)attrval); 
    370                          
    371                                         if(g_str_equal(attrval, "string")) 
    372                                                 prop_attr->gtype = MGD_TYPE_STRING; 
    373  
    374                                         if(g_str_equal(attrval, "integer")) 
    375                                                 prop_attr->gtype = MGD_TYPE_INT; 
    376  
    377                                         if(g_str_equal(attrval, "unsigned integer")) 
    378                                                 prop_attr->gtype = MGD_TYPE_UINT; 
    379  
    380                                         if(g_str_equal(attrval, "float")) 
    381                                                 prop_attr->gtype = MGD_TYPE_FLOAT; 
    382                                          
    383                                         /* FIXME, change to MGD_TYPE_DOUBLE once mgdschema supports it */ 
    384                                         if(g_str_equal(attrval, "double")) 
    385                                                 prop_attr->gtype = MGD_TYPE_FLOAT; 
    386  
    387                                         if(g_str_equal(attrval, "boolean")) 
    388                                                 prop_attr->gtype = MGD_TYPE_BOOLEAN; 
    389  
    390                                         if(g_str_equal(attrval, "bool")) 
    391                                                 prop_attr->gtype = MGD_TYPE_BOOLEAN; 
    392                                  
    393                                         if(g_str_equal(attrval, "datetime")) 
    394                                                 prop_attr->gtype = MGD_TYPE_TIMESTAMP; 
    395                                  
    396                                         if(g_str_equal(attrval, "longtext")) 
    397                                                 prop_attr->gtype = MGD_TYPE_LONGTEXT; 
    398                                  
    399                                         if(g_str_equal(attrval, "text")) 
    400                                                 prop_attr->gtype = MGD_TYPE_LONGTEXT;                            
    401  
    402                                         if(g_str_equal(attrval, "guid")) 
    403                                                 prop_attr->gtype = MGD_TYPE_GUID; 
    404                                  
     368                                if (strv_contains(schema_allowed_types, attrval)) {                                      
     369         
     370                                        midgard_core_schema_type_property_set_gtype(prop_attr, (const gchar *)attrval);                                                          
    405371                                } else { 
    406372 
    407                                         prop_attr->type = g_strdup("string"); 
    408                                         prop_attr->gtype = MGD_TYPE_STRING; 
    409                                         g_debug("Setting string type for declared %s type", attrval); 
     373                                        __warn_msg(node, "Unknown type"); 
    410374                                } 
    411375 
     
    553517                        if (g_str_equal(attr->name, "unique")) { 
    554518 
    555                                 attrval = xmlNodeListGetString (node->doc, attr->children, 1); 
    556  
    557                                 if (g_str_equal(attrval, "yes")) { 
     519                                //attrval = xmlNodeListGetString (node->doc, attr->children, 1); 
     520                                attrval = xmlGetProp(node, (const xmlChar*)"unique"); 
     521 
     522                                if (attrval && g_str_equal(attrval, "yes")) { 
    558523                                         
    559524                                        if (prop_attr->gtype != MGD_TYPE_STRING)  
     
    561526 
    562527                                        gchar *propname = (gchar *)xmlGetProp(node, (const xmlChar *)"name"); 
    563                                         type_attr->unique_name = propname; 
     528                                        type_attr->unique_name = g_strdup(propname); 
     529                                        g_free(propname); 
    564530                                } 
    565531 
    566                                 xmlFree(attrval); 
     532                                //if (attrval != NULL) 
     533                                        //xmlFree(attrval); 
    567534                        } 
    568535         
     
    619586                                                        attrval); 
    620587                                } 
    621                                 prop_attr->table = g_strdup((gchar *)attrval); 
     588 
     589                                midgard_core_schema_type_property_set_table(prop_attr, (const gchar *)attrval); 
    622590                        } 
    623591 
     
    640608                                        xmlFree(tmpattr); 
    641609                                } else { 
    642                                         g_warning("upfield redefined!"); 
     610                                        __warn_msg(node, "Upfield redefined!"); 
    643611                                } 
    644612                                prop_attr->upfield = g_strdup((gchar *)attrval);                         
     
    662630                                        xmlFree(tmpattr); 
    663631                                } else {                          
    664                                         g_warning("parentfield redefined!"); 
     632                                        __warn_msg(node, "Parentfield redefined!"); 
    665633                                } 
    666634                                prop_attr->parentfield = g_strdup((gchar *)attrval); 
     
    750718                                /* Check if type name is reserved one */ 
    751719                                if (strv_contains(rtypes, nv)) { 
    752                                         g_critical("'%s' is reserved type name", 
    753                                                         nv); 
     720                                        g_critical("'%s' is reserved type name", nv); 
    754721 
    755722                                } 
     
    764731                                        } else { 
    765732                                                type_attr = _mgd_schema_type_attr_new(); 
     733                                                type_attr->name = g_strdup((gchar *)nv); 
    766734                                                g_hash_table_insert(schema->types, 
    767735                                                                g_strdup((gchar *)nv), type_attr); 
    768                                                 _get_type_attributes (obj, type_attr); 
     736                                                _get_type_attributes (obj, type_attr, schema); 
    769737                                        } 
    770738                                }  
     
    786754                                        /* FIXME 
    787755                                         * one prop_attr seems to be assigned nowhere */ 
    788                                         prop_attr = _mgd_schema_property_attr_new(); 
     756                                        prop_attr = midgard_core_schema_type_property_attr_new(); 
    789757                                        midgard_core_schema_get_property_type(obj, type_attr, prop_attr); 
    790758                                        midgard_core_schema_get_default_value(obj, type_attr, prop_attr); 
     
    801769                                                g_free(tmpstr); 
    802770                                        } 
     771                                        prop_attr->name = g_strdup((gchar *)nv); 
    803772                                        g_hash_table_insert(type_attr->prophash,  
    804773                                                        g_strdup((gchar *)nv), prop_attr); 
     
    833802                        } 
    834803 
     804                        if (obj->children != NULL) 
     805                                _get_element_names (obj->children, type_attr, schema);   
     806 
    835807                        xmlFree(nv); 
    836                         if (obj->children != NULL) 
    837                                 _get_element_names (obj->children, type_attr, schema);    
    838808                } 
    839809        } 
     
    848818        MgdSchemaPropertyAttr *prop_attr = (MgdSchemaPropertyAttr *) value; 
    849819        const gchar *table, *tables, *primary, *parentname, *ext_table = NULL; 
    850         gchar *tmp_sql = NULL , *nick = "";      
    851         /* type_attr->num_properties is used ( and is mandatory! )  
    852          * when we register new object types and set class properties */ 
    853         guint n = ++type_attr->num_properties;; 
    854820        const gchar *pname = (gchar *) key; 
    855821        const gchar *fname = NULL, *upfield = NULL, *parentfield = NULL;  
    856822        gchar *tmpstr = NULL; 
    857         GParamSpec **params = type_attr->params; 
    858         GString *tmp_gstring_sql, *table_sql; 
    859          
    860         /* Set default string type if not set */ 
    861         if(!prop_attr->type) { 
    862                 prop_attr->type = g_strdup("string"); 
    863                 prop_attr->gtype = MGD_TYPE_STRING; 
    864         }                
    865823         
    866824        table = prop_attr->table; 
     
    868826        parentname = table; 
    869827 
    870         /* TODO 
    871          * Set ACL data, create sql queries, add additional data 
    872          * All data required is present at this moment. 
    873          */ 
    874          
    875         /* Search for upfield and parentfield definition. 
    876          * We will use them ( if found ) for nick ( table.field ) definition  
    877          * without need to define field attribute.  */ 
    878          
    879828        upfield = prop_attr->upfield; 
    880829        parentfield = prop_attr->parentfield; 
     
    885834 
    886835        ext_table = table; 
    887         g_hash_table_insert(type_attr->tableshash, g_strdup(table), NULL); 
    888  
    889         /* "external" tables for type */ 
    890          
    891         /* Create GHashTable for all tables described in type's schema definition */ 
     836         
    892837        if (ext_table != NULL){ 
    893                                  
    894                 table_sql = g_string_new(""); 
    895                 if(type_attr->tmp_select) 
    896                         g_string_append(table_sql, type_attr->tmp_select); 
    897                  
    898                 if (prop_attr->is_multilang) 
    899                         type_attr->use_lang = TRUE; 
    900          
    901                 fname = prop_attr->field; 
    902  
    903                 prop_attr->table = g_strdup(ext_table);  
    904  
    905                 if (fname != NULL) { 
    906                         tmpstr = g_strjoin(".", ext_table, fname,NULL); 
    907                 } else { 
    908                         tmpstr = g_strjoin(".", ext_table, pname,NULL);  
    909                 } 
    910                 prop_attr->tablefield = g_strdup(tmpstr);  
    911                 //nick = g_strdup(tmpstr); /* FIXME, LEAK */ 
    912                  
    913                 tmp_gstring_sql = g_string_new(" ");     
    914                 g_string_append_printf(tmp_gstring_sql, 
    915                                 "%s AS %s", tmpstr, pname); 
    916                 g_free(tmpstr); 
    917                 tmpstr = g_string_free(tmp_gstring_sql, FALSE); 
    918                 /* Avoid duplicated coma */ 
    919                 if(type_attr->tmp_select) 
    920                         g_string_append(table_sql, ", "); 
    921                 g_string_append(table_sql, tmpstr); 
    922                 g_free(tmpstr); 
    923                 g_free(type_attr->tmp_select); 
    924                 type_attr->tmp_select = g_string_free(table_sql, FALSE); 
    925                          
    926                 /* "external" tables end */ 
     838                 
     839                fname = prop_attr->field;  
     840                midgard_core_schema_type_property_set_tablefield(prop_attr, ext_table, fname ? fname : pname);           
    927841        }  
    928842         
     
    948862        }        
    949863 
    950         if(primary != NULL) { 
    951                 nick = g_strjoin(".", table, primary, NULL); 
    952                 if(prop_attr->tablefield != NULL) 
    953                         g_free((gchar *)prop_attr->tablefield); 
    954                 prop_attr->tablefield = g_strjoin(".", table, primary, NULL); 
    955                 tmpstr = g_strconcat(nick, " AS ", pname, NULL); 
    956                 tmp_sql = g_strjoin(",", tmpstr, type_attr->tmp_select,NULL); 
    957                 if(type_attr->tmp_select) 
    958                         g_free(type_attr->tmp_select); 
    959                 type_attr->tmp_select = g_strdup(tmp_sql); 
    960                 g_free(tmpstr); 
    961                 g_free(tmp_sql);                        
    962                 g_free(nick); 
    963         } 
    964  
    965         /* Set field which is used as up. 
    966          * At the same time we define property_up which keeps such data  */  
    967         if(upfield != NULL) { 
    968                 nick = g_strjoin(".", table, upfield, NULL); 
    969                 if(prop_attr->tablefield != NULL) 
    970                         g_free((gchar *)prop_attr->tablefield); 
    971                 prop_attr->tablefield = g_strjoin(".", table, upfield, NULL); 
    972                 tmpstr = g_strconcat(nick, " AS ", pname, NULL); 
    973                 tmp_sql = g_strjoin(",", tmpstr, type_attr->tmp_select,NULL); 
    974                 if(type_attr->tmp_select) 
    975                         g_free(type_attr->tmp_select); 
    976                 type_attr->tmp_select = g_strdup(tmp_sql); 
    977                 g_free(tmpstr); 
    978                 g_free(tmp_sql); 
    979                 g_free(nick); 
    980         } 
    981          
    982         /* Set parentfield and property_parent */ 
    983         if(parentfield != NULL) {     
    984                 nick = g_strjoin(".", table, parentfield, NULL); 
    985                 if(prop_attr->tablefield != NULL) 
    986                         g_free((gchar *)prop_attr->tablefield); 
    987                 prop_attr->tablefield = g_strjoin(".", table, parentfield, NULL); 
    988                 tmpstr = g_strconcat(nick, " AS ", pname, NULL); 
    989                 tmp_sql = g_strjoin(",", tmpstr, type_attr->tmp_select,NULL); 
    990                 if(type_attr->tmp_select) 
    991                         g_free(type_attr->tmp_select); 
    992                 type_attr->tmp_select = g_strdup(tmp_sql); 
    993                 g_free(tmpstr); 
    994                 g_free(tmp_sql); 
    995                 g_free(nick); 
    996         } 
     864        if(primary != NULL && table != NULL)     
     865                midgard_core_schema_type_property_set_tablefield(prop_attr, table, primary); 
     866 
     867        if(upfield != NULL && table != NULL) 
     868                midgard_core_schema_type_property_set_tablefield(prop_attr, table, upfield); 
     869         
     870        if(parentfield != NULL && table != NULL)  
     871                midgard_core_schema_type_property_set_tablefield(prop_attr, table, parentfield); 
    997872 
    998873        if(prop_attr->field == NULL) 
     
    1002877        if((prop_attr->is_primary) && (prop_attr->gtype != G_TYPE_UINT)) 
    1003878                prop_attr->gtype = G_TYPE_UINT; 
    1004                          
    1005         nick = NULL; 
    1006         /* Create param_specs for object's properties */ 
    1007  
    1008         if(prop_attr->description == NULL) 
    1009                 prop_attr->description = g_strdup(""); 
    1010  
    1011         GType ptype = prop_attr->gtype; 
    1012                  
    1013         if (ptype == MGD_TYPE_STRING) { 
    1014  
    1015                 params[n-1] = g_param_spec_string( 
    1016                                 pname, nick, prop_attr->description, 
    1017                                 "",  G_PARAM_READWRITE); 
    1018  
    1019         } else if (ptype == MGD_TYPE_TIMESTAMP) { 
    1020                  
    1021                 params[n-1] = g_param_spec_boxed( 
    1022                                 pname, nick, prop_attr->description, 
    1023                                 MGD_TYPE_TIMESTAMP, G_PARAM_READWRITE); 
    1024  
    1025         } else if (ptype == MGD_TYPE_UINT) { 
    1026                  
    1027                 params[n-1] = g_param_spec_uint( 
    1028                                 pname, nick, prop_attr->description, 
    1029                                 0, G_MAXUINT32, 0, G_PARAM_READWRITE); 
    1030          
    1031         } else if (ptype == MGD_TYPE_INT) { 
    1032                  
    1033                 params[n-1] = g_param_spec_int( 
    1034                                 pname, nick, prop_attr->description, 
    1035                                 G_MININT32, G_MAXINT32, 0, G_PARAM_READWRITE); 
    1036  
    1037         } else if (ptype == MGD_TYPE_FLOAT) { 
    1038                  
    1039                 params[n-1] = g_param_spec_float( 
    1040                                 pname, nick, prop_attr->description, 
    1041                                 -G_MAXFLOAT, G_MAXFLOAT, 0, G_PARAM_READWRITE); 
    1042          
    1043         } else if (ptype == MGD_TYPE_BOOLEAN) { 
    1044                  
    1045                 params[n-1] = g_param_spec_boolean( 
    1046                                 pname, nick, prop_attr->description, 
    1047                                 FALSE, G_PARAM_READWRITE); 
    1048          
    1049         } else { 
    1050                  
    1051                 params[n-1] = g_param_spec_string( 
    1052                                 pname, nick, prop_attr->description, 
    1053                                 "", G_PARAM_READWRITE);                          
    1054         }  
    1055  
    1056         g_free(prop_attr->description); 
    1057 
    1058  
    1059 /* Append all tables' select to type's full_select */ 
    1060 void _set_object_full_select(gpointer key, gpointer value, gpointer userdata) 
    1061 
    1062         GString *fullselect = (GString *) userdata; 
    1063 
    1064  
     879
    1065880 
    1066881/* Get types' data. Type's name and its values. 
     
    1070885 * with correct values 
    1071886 */  
    1072  
    1073 typedef struct { 
    1074         GString *string; 
    1075         guint elts; 
    1076 }_str_cont; 
    1077  
    1078 static void __build_tables_string( 
    1079                 gpointer key, gpointer value, gpointer user_data) 
    1080 { 
    1081         _str_cont *_cont  = (_str_cont *) user_data; 
    1082          
    1083         if(_cont->elts == 0) 
    1084                 g_string_append_printf(_cont->string, "%s", (gchar *) key); 
    1085         else  
    1086                 g_string_append_printf(_cont->string, ", %s", (gchar *) key); 
    1087          
    1088         _cont->elts++; 
    1089 } 
    1090  
    1091887void __get_tdata_foreach(gpointer key, gpointer value, gpointer user_data) 
    1092 
    1093         GType new_type; 
     888{        
    1094889        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *) value; 
    1095890        guint np;                
     
    1100895        np = g_hash_table_size(type_attr->prophash); 
    1101896 
    1102         type_attr->params = g_malloc(sizeof(GParamSpec*)*(np+1));  
    1103  
    1104897        if (np > 0) { 
     898 
    1105899                g_hash_table_foreach(type_attr->prophash,  
    1106900                                __get_pdata_foreach, type_attr); 
    1107  
    1108                 GString *_tables = g_string_new(""); 
    1109                 _str_cont *cont = g_new(_str_cont, 1); 
    1110                 cont->string = _tables; 
    1111                 cont->elts = 0; 
    1112                  
    1113                 g_hash_table_foreach(type_attr->tableshash, 
    1114                                 __build_tables_string, cont); 
    1115                 g_free(cont); 
    1116  
    1117                 type_attr->tables = g_string_free(_tables, FALSE); 
    1118                  
    1119                 /* add NULL as last value,  
    1120                  * we will use ud.param as GParamSpec for object's properties. */  
    1121                  
    1122                 type_attr->params[np] = NULL; 
    1123                  
    1124                 /* Define tree management fields and tables */ 
    1125                 //type_attr->parent = typename; 
    1126                  
    1127                 /* Set NULL to child_cname, we will fill this value when all types 
    1128                  * are already registered ( _schema_postconfig ).  */  
    1129                 type_attr->childs = NULL; 
    1130                  
    1131                 GString *fullselect = g_string_new(""); 
    1132                 g_string_append(fullselect , type_attr->tmp_select ); 
    1133                 g_hash_table_foreach(type_attr->tableshash,   
    1134                                 _set_object_full_select, fullselect); 
    1135  
    1136                 type_attr->sql_select_full = g_string_free(fullselect, FALSE); 
    1137  
    1138                 /* Register type , and initialize class. We can not add properties while  
    1139                  * class is registered and we can not initialize class with properties later. 
    1140                  * Or rather "we should not" do this later. */  
    1141                 if (type_attr->params != NULL) { 
    1142  
    1143                         new_type = midgard_type_register(key, type_attr, MIDGARD_TYPE_OBJECT); 
    1144                         if (new_type) { 
    1145                                 /* Initialize objects so we have properties  
    1146                                  * private data assigned before "real" application  
    1147                                  * start */ 
    1148                                 GObject *foo = g_object_new(new_type, NULL); 
    1149                                 /* Set number of properties. 
    1150                                  * This way we gain performance for instance_init call */ 
    1151                                 GParamSpec **pspecs =  
    1152                                         g_object_class_list_properties( 
    1153                                                         G_OBJECT_GET_CLASS(G_OBJECT(foo)),  
    1154                                                         &type_attr->class_nprop); 
    1155                                 g_free(pspecs); 
    1156                                 g_object_unref(foo);  
    1157                         } 
    1158                 } 
    1159          
     901                 
    1160902        } else { 
     903 
    1161904                g_warning("Type %s has less than 1 property!", (gchar *)key); 
    1162905        } 
     
    1179922 
    1180923/* We CAN NOT define some data during __get_tdata_foreach. 
    1181  * parent and childs relation ( for example ) must be done AFTER 
     924 * parent and children relation ( for example ) must be done AFTER 
    1182925 * all types are registered and all types internal structures are 
    1183926 * already initialized and defined 
    1184927 */  
    1185 void __postconfig_schema_foreach(gpointer key, gpointer value, gpointer user_data) 
    1186 
    1187         MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *) value, *parenttype; 
    1188         MidgardSchema *schema = (MidgardSchema *) user_data; 
     928void __postconfig_schema_foreach(gpointer key, gpointer value, gpointer userdata) 
     929
     930        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *) value; 
     931        MgdSchemaTypeAttr *parenttype = NULL; 
     932        MidgardSchema *schema = (MidgardSchema *) userdata; 
    1189933        gchar *typename = (gchar *) key; 
    1190934        const gchar *parentname; 
     
    1193937         
    1194938        if (parentname  != NULL ){ 
    1195  
    1196                 /* validate tree parent class */ 
    1197                 MidgardObjectClass *pklass = MIDGARD_OBJECT_GET_CLASS_BY_NAME(parentname); 
    1198                 if(pklass == NULL) { 
    1199                          
    1200                         g_critical("Parent %s for %s class is not registered in GType system", 
    1201                                         parentname, typename); 
    1202                 } 
    1203  
    1204                 /* validate parent property */ 
    1205                 MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS_BY_NAME(typename); 
    1206                 const gchar *parent_property = midgard_object_class_get_property_parent(klass); 
    1207                 if(parent_property == NULL) { 
    1208                          
    1209                         g_critical("Parent property missed for %s class. %s declared as tree parent class", 
    1210                                         typename, parentname); 
    1211                 } 
    1212939 
    1213940                /* Set child type name for parent's one */ 
     
    1227954 
    1228955                if ((parenttype = midgard_schema_lookup_type(schema, (gchar *)parentname)) != NULL){ 
    1229                         /* g_debug("type %s, parent %s", typename, parentname); */ 
    1230                         if (!g_slist_find(parenttype->childs,  
     956                        // g_debug("type %s, parent %s", typename, parentname);  
     957                        if (!g_slist_find(parenttype->children,  
    1231958                                                (gpointer)g_type_from_name(typename))) { 
    1232                                 parenttype->childs =  
    1233                                         g_slist_append(parenttype->childs,  
     959                                parenttype->children =  
     960                                        g_slist_append(parenttype->children,  
    1234961                                                        (gpointer)g_type_from_name(typename)); 
    1235962                        }                        
    1236                 } 
    1237         } 
     963                }  
     964        }               
    1238965} 
    1239966 
     
    16231350} 
    16241351 
     1352static void __extend_type_attr(gpointer key, gpointer val, gpointer userdata) 
     1353{ 
     1354        gchar *property = (gchar *)key; 
     1355        MgdSchemaPropertyAttr *parent_attr = (MgdSchemaPropertyAttr *) val; 
     1356        MgdSchemaTypeAttr *type = (MgdSchemaTypeAttr *) userdata; 
     1357 
     1358        /* Look for property registered for child type. If it is registered we silently 
     1359           return. Child type may use different field for inherited property name */ 
     1360        MgdSchemaPropertyAttr *prop_attr = g_hash_table_lookup(type->prophash, key); 
     1361 
     1362        if (prop_attr)  
     1363                return; 
     1364         
     1365        midgard_core_schema_type_property_copy(parent_attr, type); 
     1366} 
     1367 
     1368static void __extend_type_foreach(gpointer key, gpointer val, gpointer userdata) 
     1369{ 
     1370        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *) val; 
     1371        MidgardSchema *schema = (MidgardSchema*) userdata; 
     1372 
     1373        if (val == NULL) return; 
     1374        if (type_attr->extends == NULL) return; 
     1375 
     1376        MgdSchemaTypeAttr *parent_type_attr =  
     1377                midgard_schema_lookup_type(schema, type_attr->extends); 
     1378 
     1379        if (!parent_type_attr) 
     1380                g_error("Type information for %s (%s's parent) not found",  
     1381                                type_attr->extends, type_attr->name); 
     1382 
     1383        /* Use parent's storage */ 
     1384        type_attr->table = g_strdup(parent_type_attr->table); 
     1385        type_attr->tables = g_strdup(parent_type_attr->tables); 
     1386 
     1387        g_hash_table_foreach(parent_type_attr->prophash, __extend_type_attr, type_attr);         
     1388} 
     1389 
     1390static void __copy_type_attr(gpointer key, gpointer val, gpointer userdata) 
     1391{ 
     1392        gchar *property = (gchar *)key; 
     1393        MgdSchemaPropertyAttr *parent_attr = (MgdSchemaPropertyAttr *) val; 
     1394        MgdSchemaTypeAttr *type = (MgdSchemaTypeAttr *) userdata; 
     1395 
     1396        /* Look for property registered for child type. If it is registered we silently 
     1397           return. Child type may use different field for inherited property name */ 
     1398        MgdSchemaPropertyAttr *prop_attr = g_hash_table_lookup(type->prophash, key); 
     1399 
     1400        if (prop_attr)  
     1401                return; 
     1402         
     1403        midgard_core_schema_type_property_copy(parent_attr, type); 
     1404 
     1405        prop_attr = g_hash_table_lookup(type->prophash, key); 
     1406 
     1407        /* redefine tablefield */ 
     1408        midgard_core_schema_type_property_set_tablefield(prop_attr, type->table, prop_attr->field); 
     1409         
     1410} 
     1411 
     1412static void __copy_type_foreach(gpointer key, gpointer val, gpointer userdata) 
     1413{ 
     1414        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *) val; 
     1415        MidgardSchema *schema = (MidgardSchema*) userdata; 
     1416 
     1417        gchar *copied = type_attr->copy_from; 
     1418 
     1419        if (val == NULL) return; 
     1420        if (copied == NULL) return; 
     1421 
     1422        MgdSchemaTypeAttr *parent_type_attr =  
     1423                midgard_schema_lookup_type(schema, copied); 
     1424 
     1425        if (!parent_type_attr) 
     1426                g_error("Type information for %s (%s's parent) not found",  
     1427                                copied, type_attr->name); 
     1428 
     1429        g_hash_table_foreach(parent_type_attr->prophash, __copy_type_attr, type_attr);   
     1430} 
     1431 
     1432static void __register_schema_type (gpointer key, gpointer val, gpointer user_data) 
     1433{ 
     1434        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *) val; 
     1435 
     1436        if (val == NULL) return; 
     1437        if (type_attr->params == NULL) { 
     1438 
     1439                g_warning("No parameters found for %s schema type. Not registering.", type_attr->name); 
     1440                return; 
     1441        } 
     1442 
     1443        GType new_type; 
     1444        new_type = midgard_type_register(key, type_attr, MIDGARD_TYPE_OBJECT); 
     1445 
     1446        if (new_type) { 
     1447 
     1448                GObject *foo = g_object_new(new_type, NULL); 
     1449                /* Set number of properties. 
     1450                 * This way we gain performance for instance_init call */ 
     1451                GParamSpec **pspecs =  
     1452                        g_object_class_list_properties( 
     1453                                        G_OBJECT_GET_CLASS(G_OBJECT(foo)),  
     1454                                        &type_attr->class_nprop); 
     1455                g_free(pspecs); 
     1456                g_object_unref(foo);  
     1457        } 
     1458} 
     1459 
     1460static void __build_static_sql (gpointer key, gpointer val, gpointer userdata) 
     1461{ 
     1462        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *)val; 
     1463        midgard_core_schema_type_build_static_sql (type_attr); 
     1464} 
     1465 
     1466static void __initialize_paramspec (gpointer key, gpointer val, gpointer userdata) 
     1467{ 
     1468        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *)val; 
     1469        midgard_core_schema_type_initialize_paramspec (type_attr); 
     1470} 
     1471 
     1472static void __validate_fields (gpointer key, gpointer val, gpointer userdata) 
     1473{ 
     1474        MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *)val; 
     1475        midgard_core_schema_type_validate_fields (type_attr); 
     1476} 
     1477 
     1478static void __midgard_schema_postconfig(MidgardSchema *self) 
     1479{ 
     1480        g_assert(self != NULL); 
     1481 
     1482        g_hash_table_foreach (self->types, __extend_type_foreach, self); 
     1483        g_hash_table_foreach (self->types, __copy_type_foreach, self); 
     1484        g_hash_table_foreach (self->types, __initialize_paramspec, NULL); 
     1485        g_hash_table_foreach (self->types, __build_static_sql, NULL); 
     1486        g_hash_table_foreach (self->types, __validate_fields, NULL); 
     1487        g_hash_table_foreach (self->types, __register_schema_type, NULL); 
     1488} 
     1489 
    16251490/** 
    16261491 * midgard_schema_read_dir: 
     
    16401505        gint visible = 0; 
    16411506        const gchar *lschema_dir = dirname; 
    1642  
    1643         MidgardSchema *gschema = self; 
    16441507 
    16451508        if (dirname == NULL) { 
     
    16781541                                if(visible == 1){                                        
    16791542                                        /* FIXME, use fpath here */ 
    1680                                         midgard_schema_read_file(gschema, fpfname); 
     1543                                        midgard_schema_read_file(self, fpfname); 
    16811544                                } 
    16821545                        } 
     
    16861549                         * Glib itself is responsible for data returned from g_dir_read_name */ 
    16871550                } 
     1551 
     1552                /* post parsing routines */ 
     1553                __midgard_schema_postconfig(self); 
    16881554 
    16891555                /* validate */ 
  • trunk/midgard/core/midgard/src/midgard_core_schema.c

    r22233 r22248  
    2323        GString *string; 
    2424        guint elts; 
     25        MgdSchemaTypeAttr *type; 
    2526}_str_cont; 
    2627 
     
    312313        midgard_core_schema_type_property_set_table(prop, table); 
    313314 
     315        /* Set field implicitly */ 
     316        //g_free(prop->field); /* FIXME */ 
     317        prop->field = g_strdup((gchar *)field); 
     318 
    314319        prop->tablefield = g_strjoin(".", table, field, NULL); 
    315320} 
     
    366371        gchar *property = (gchar *) key; 
    367372        MgdSchemaPropertyAttr *prop_attr = (MgdSchemaPropertyAttr *)val; 
     373        MgdSchemaTypeAttr *type = _cont->type; 
     374 
     375        /* Check if property attributes are correct */ 
     376        /* Set missed table and tablefield */ 
     377        if (prop_attr->table == NULL) { 
     378                midgard_core_schema_type_property_set_tablefield(prop_attr, type->table, prop_attr->field); 
     379        } 
     380 
     381        /* upfield defined, set tablefield */ 
     382        if (prop_attr->upfield != NULL)  
     383                midgard_core_schema_type_property_set_tablefield(prop_attr, prop_attr->table, prop_attr->upfield); 
     384         
     385        /* parentfield defined, set tablefield */ 
     386        if (prop_attr->parentfield != NULL)  
     387                midgard_core_schema_type_property_set_tablefield(prop_attr, prop_attr->table, prop_attr->parentfield); 
    368388 
    369389        if(_cont->elts == 0) 
     
    387407        cont->string = _sql; 
    388408        cont->elts = 0; 
     409        cont->type = type_attr; 
    389410 
    390411        g_hash_table_foreach (type_attr->prophash, __build_static_sql, cont); 
    391412 
    392         //g_warning("STATIC SQL: %s", _sql->str); 
    393 
     413        if (_sql->str == NULL) 
     414                return; 
     415 
     416        type_attr->sql_select_full = g_strdup(_sql->str); 
     417
     418 
     419static void __field_is_equal(gpointer key, gpointer val, gpointer userdata) 
     420
     421        gchar *property = (gchar *)key; 
     422        MgdSchemaPropertyAttr *prop_attr = (MgdSchemaPropertyAttr *)val; 
     423        MgdSchemaPropertyAttr *src_prop = (MgdSchemaPropertyAttr *)userdata; 
     424 
     425        if (!g_str_equal(prop_attr->name, src_prop->name)) { 
     426 
     427                if (g_str_equal(prop_attr->tablefield, src_prop->tablefield)) { 
     428 
     429                        g_warning("Field %s redefined for %s and %s",  
     430                                        prop_attr->tablefield, prop_attr->name, src_prop->name); 
     431                        g_error("Table columns collision"); 
     432                } 
     433        } 
     434
     435 
     436static void __check_field_duplicates(gpointer key, gpointer val, gpointer userdata) 
     437
     438        gchar *property = (gchar *)key; 
     439        MgdSchemaPropertyAttr *prop_attr = (MgdSchemaPropertyAttr *)val; 
     440        MgdSchemaTypeAttr *type = (MgdSchemaTypeAttr *)userdata; 
     441 
     442        g_hash_table_foreach(type->prophash, __field_is_equal, prop_attr); 
     443
     444 
     445void 
     446midgard_core_schema_type_validate_fields (MgdSchemaTypeAttr *type) 
     447
     448        g_assert(type != NULL); 
     449        g_hash_table_foreach(type->prophash, __check_field_duplicates, type); 
     450
  • trunk/midgard/core/midgard/src/midgard_object.c

    r22216 r22248  
    29242924        MIDGARD_ERRNO_SET(object->dbpriv->mgd, MGD_ERR_OK); 
    29252925 
    2926         GSList *childs = NULL; 
    2927         childs = object->dbpriv->storage_data->childs
    2928  
    2929         if ((childcname == NULL) || (object->dbpriv->storage_data->childs == NULL)) { 
     2926        GSList *children = NULL; 
     2927        children = object->dbpriv->storage_data->children
     2928 
     2929        if ((childcname == NULL) || (object->dbpriv->storage_data->children == NULL)) { 
    29302930                MIDGARD_ERRNO_SET(object->dbpriv->mgd, MGD_ERR_NOT_EXISTS);     
    29312931                return NULL; 
    29322932        } 
    29332933         
    2934         if(!g_slist_find(object->dbpriv->storage_data->childs, (gpointer)g_type_from_name(childcname))) { 
     2934        if(!g_slist_find(object->dbpriv->storage_data->children, (gpointer)g_type_from_name(childcname))) { 
    29352935                MIDGARD_ERRNO_SET(object->dbpriv->mgd, MGD_ERR_NOT_EXISTS); 
    29362936                g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, 
     
    30173017 
    30183018        GSList *list = NULL; 
    3019         GSList *children = self->dbpriv->storage_data->childs; /* FIXME, make it proper English ;) */ 
     3019        GSList *children = self->dbpriv->storage_data->children; 
    30203020 
    30213021        for (list = children ; list != NULL; list = list->next) { 
  • trunk/midgard/core/midgard/src/midgard_object_class.c

    r21903 r22248  
    144144 
    145145        _GET_TYPE_ATTR(klass); 
    146         if(!type_attr->childs
     146        if(!type_attr->children
    147147                return NULL; 
    148148         
    149         GSList *slist = type_attr->childs
     149        GSList *slist = type_attr->children
    150150        guint i = 0; 
    151151        MidgardObjectClass **children =  
  • trunk/midgard/core/midgard/src/schema.h

    r22233 r22248  
    6868        gchar *primaryfield; 
    6969        gboolean use_lang; 
    70         GSList *childs
     70        GSList *children
    7171        guint property_count; 
    7272        gchar *tmp_select;       
     
    9696void                    midgard_core_schema_type_build_static_sql       (MgdSchemaTypeAttr *type_attr); 
    9797void                    midgard_core_schema_type_initialize_paramspec   (MgdSchemaTypeAttr *type); 
    98  
     98void                    midgard_core_schema_type_validate_fields        (MgdSchemaTypeAttr *type); 
    9999 
    100100/* RESERVED WORDS */