Changeset 22248
- Timestamp:
- 05/20/09 13:42:27 (1 year ago)
- Files:
-
- trunk/midgard/core/midgard/Makefile.am (modified) (1 diff)
- trunk/midgard/core/midgard/src/mgdschema.c (modified) (36 diffs)
- trunk/midgard/core/midgard/src/midgard_core_schema.c (modified) (4 diffs)
- trunk/midgard/core/midgard/src/midgard_object.c (modified) (2 diffs)
- trunk/midgard/core/midgard/src/midgard_object_class.c (modified) (1 diff)
- trunk/midgard/core/midgard/src/schema.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/midgard/core/midgard/Makefile.am
r22077 r22248 125 125 src/midgard_core_config.h \ 126 126 src/midgard_core_object_parameter.h \ 127 src/midgard_core_schema.c \ 128 src/midgard_core_xml.h \ 129 src/midgard_core_xml.c \ 127 130 src/midgard_dbus.h \ 128 131 src/midgard_dbus.c \ trunk/midgard/core/midgard/src/mgdschema.c
r22218 r22248 1 1 /* Midgard schema , records and objects definition. 2 2 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> 4 4 5 5 This program is free software; you can redistribute it and/or modify it … … 32 32 #include <libxml/parserInternals.h> 33 33 #include "guid.h" 34 #include "midgard_core_xml.h" 34 35 35 36 /* TODO tune header files , no need to include string.h while we need to include midgard.h in almost every case */ … … 45 46 static const gchar *parsed_schema = NULL; 46 47 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 94 48 void _destroy_property_hash(gpointer key, gpointer value, gpointer userdata) 95 49 { … … 113 67 { 114 68 MgdSchemaTypeAttr *type = g_new(MgdSchemaTypeAttr, 1); 69 type->name = NULL; 115 70 type->base_index = 0; 116 71 type->num_properties = 0; … … 131 86 type->tableshash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); 132 87 type->prophash = g_hash_table_new(g_str_hash, g_str_equal); 133 type->child s= NULL;88 type->children = NULL; 134 89 type->unique_name = NULL; 135 90 type->sql_select_full = NULL; 136 type->tmp_select = NULL; 91 type->copy_from = NULL; 92 type->extends = NULL; 137 93 138 94 return type; … … 142 98 { 143 99 g_assert(type != NULL); 100 101 g_free(type->name); 102 type->name = NULL; 144 103 145 104 g_free((gchar *)type->table); … … 155 114 g_hash_table_destroy(type->prophash); 156 115 157 g_free(type->tmp_select);158 116 g_free(type->sql_select_full); 159 117 g_free(type->parentfield); … … 217 175 * We change them only here , and in xml file itself. 218 176 */ 219 static const gchar *mgd_complextype[] = { "type", "property", "Schema", "description", "include", NULL };177 static const gchar *mgd_complextype[] = { "type", "property", "Schema", "description", "include", "copy", "extends", NULL }; 220 178 static 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, 223 184 "parent", 224 185 "parentfield", 225 "type",226 186 "link", 227 187 "upfield", … … 310 270 /* Get all type attributes */ 311 271 static void 312 _get_type_attributes(xmlNode * node, MgdSchemaTypeAttr *type_attr )272 _get_type_attributes(xmlNode * node, MgdSchemaTypeAttr *type_attr, MidgardSchema *schema) 313 273 { 314 274 xmlAttr *attr; … … 322 282 while (attr != NULL){ 323 283 324 if (!strv_contains(mgd_attribute, attr->name)){284 if (!strv_contains(mgd_attribute, attr->name)){ 325 285 g_warning("Wrong attribute '%s' in '%s' on line %ld", 326 286 attr->name, parsed_schema, xmlGetLineNo(node)); 327 287 } 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); 341 309 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); 343 347 } 344 348 } … … 348 352 MgdSchemaTypeAttr *type_attr, MgdSchemaPropertyAttr *prop_attr) 349 353 { 350 gboolean typeisset = FALSE;351 354 xmlAttr *attr; 352 355 xmlChar *attrval; … … 363 366 attrval = xmlNodeListGetString (node->doc, attr->children, 1); 364 367 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); 405 371 } else { 406 372 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"); 410 374 } 411 375 … … 553 517 if (g_str_equal(attr->name, "unique")) { 554 518 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")) { 558 523 559 524 if (prop_attr->gtype != MGD_TYPE_STRING) … … 561 526 562 527 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); 564 530 } 565 531 566 xmlFree(attrval); 532 //if (attrval != NULL) 533 //xmlFree(attrval); 567 534 } 568 535 … … 619 586 attrval); 620 587 } 621 prop_attr->table = g_strdup((gchar *)attrval); 588 589 midgard_core_schema_type_property_set_table(prop_attr, (const gchar *)attrval); 622 590 } 623 591 … … 640 608 xmlFree(tmpattr); 641 609 } else { 642 g_warning("upfield redefined!");610 __warn_msg(node, "Upfield redefined!"); 643 611 } 644 612 prop_attr->upfield = g_strdup((gchar *)attrval); … … 662 630 xmlFree(tmpattr); 663 631 } else { 664 g_warning("parentfield redefined!");632 __warn_msg(node, "Parentfield redefined!"); 665 633 } 666 634 prop_attr->parentfield = g_strdup((gchar *)attrval); … … 750 718 /* Check if type name is reserved one */ 751 719 if (strv_contains(rtypes, nv)) { 752 g_critical("'%s' is reserved type name", 753 nv); 720 g_critical("'%s' is reserved type name", nv); 754 721 755 722 } … … 764 731 } else { 765 732 type_attr = _mgd_schema_type_attr_new(); 733 type_attr->name = g_strdup((gchar *)nv); 766 734 g_hash_table_insert(schema->types, 767 735 g_strdup((gchar *)nv), type_attr); 768 _get_type_attributes (obj, type_attr );736 _get_type_attributes (obj, type_attr, schema); 769 737 } 770 738 } … … 786 754 /* FIXME 787 755 * 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(); 789 757 midgard_core_schema_get_property_type(obj, type_attr, prop_attr); 790 758 midgard_core_schema_get_default_value(obj, type_attr, prop_attr); … … 801 769 g_free(tmpstr); 802 770 } 771 prop_attr->name = g_strdup((gchar *)nv); 803 772 g_hash_table_insert(type_attr->prophash, 804 773 g_strdup((gchar *)nv), prop_attr); … … 833 802 } 834 803 804 if (obj->children != NULL) 805 _get_element_names (obj->children, type_attr, schema); 806 835 807 xmlFree(nv); 836 if (obj->children != NULL)837 _get_element_names (obj->children, type_attr, schema);838 808 } 839 809 } … … 848 818 MgdSchemaPropertyAttr *prop_attr = (MgdSchemaPropertyAttr *) value; 849 819 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;;854 820 const gchar *pname = (gchar *) key; 855 821 const gchar *fname = NULL, *upfield = NULL, *parentfield = NULL; 856 822 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 }865 823 866 824 table = prop_attr->table; … … 868 826 parentname = table; 869 827 870 /* TODO871 * Set ACL data, create sql queries, add additional data872 * 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 ) definition877 * without need to define field attribute. */878 879 828 upfield = prop_attr->upfield; 880 829 parentfield = prop_attr->parentfield; … … 885 834 886 835 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 892 837 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); 927 841 } 928 842 … … 948 862 } 949 863 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); 997 872 998 873 if(prop_attr->field == NULL) … … 1002 877 if((prop_attr->is_primary) && (prop_attr->gtype != G_TYPE_UINT)) 1003 878 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 } 1065 880 1066 881 /* Get types' data. Type's name and its values. … … 1070 885 * with correct values 1071 886 */ 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 else1086 g_string_append_printf(_cont->string, ", %s", (gchar *) key);1087 1088 _cont->elts++;1089 }1090 1091 887 void __get_tdata_foreach(gpointer key, gpointer value, gpointer user_data) 1092 { 1093 GType new_type; 888 { 1094 889 MgdSchemaTypeAttr *type_attr = (MgdSchemaTypeAttr *) value; 1095 890 guint np; … … 1100 895 np = g_hash_table_size(type_attr->prophash); 1101 896 1102 type_attr->params = g_malloc(sizeof(GParamSpec*)*(np+1));1103 1104 897 if (np > 0) { 898 1105 899 g_hash_table_foreach(type_attr->prophash, 1106 900 __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 1160 902 } else { 903 1161 904 g_warning("Type %s has less than 1 property!", (gchar *)key); 1162 905 } … … 1179 922 1180 923 /* We CAN NOT define some data during __get_tdata_foreach. 1181 * parent and child srelation ( for example ) must be done AFTER924 * parent and children relation ( for example ) must be done AFTER 1182 925 * all types are registered and all types internal structures are 1183 926 * already initialized and defined 1184 927 */ 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; 928 void __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; 1189 933 gchar *typename = (gchar *) key; 1190 934 const gchar *parentname; … … 1193 937 1194 938 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 }1212 939 1213 940 /* Set child type name for parent's one */ … … 1227 954 1228 955 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->child s,956 // g_debug("type %s, parent %s", typename, parentname); 957 if (!g_slist_find(parenttype->children, 1231 958 (gpointer)g_type_from_name(typename))) { 1232 parenttype->child s=1233 g_slist_append(parenttype->child s,959 parenttype->children = 960 g_slist_append(parenttype->children, 1234 961 (gpointer)g_type_from_name(typename)); 1235 962 } 1236 } 1237 } 963 } 964 } 1238 965 } 1239 966 … … 1623 1350 } 1624 1351 1352 static 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 1368 static 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 1390 static 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 1412 static 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 1432 static 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 1460 static 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 1466 static 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 1472 static 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 1478 static 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 1625 1490 /** 1626 1491 * midgard_schema_read_dir: … … 1640 1505 gint visible = 0; 1641 1506 const gchar *lschema_dir = dirname; 1642 1643 MidgardSchema *gschema = self;1644 1507 1645 1508 if (dirname == NULL) { … … 1678 1541 if(visible == 1){ 1679 1542 /* FIXME, use fpath here */ 1680 midgard_schema_read_file( gschema, fpfname);1543 midgard_schema_read_file(self, fpfname); 1681 1544 } 1682 1545 } … … 1686 1549 * Glib itself is responsible for data returned from g_dir_read_name */ 1687 1550 } 1551 1552 /* post parsing routines */ 1553 __midgard_schema_postconfig(self); 1688 1554 1689 1555 /* validate */ trunk/midgard/core/midgard/src/midgard_core_schema.c
r22233 r22248 23 23 GString *string; 24 24 guint elts; 25 MgdSchemaTypeAttr *type; 25 26 }_str_cont; 26 27 … … 312 313 midgard_core_schema_type_property_set_table(prop, table); 313 314 315 /* Set field implicitly */ 316 //g_free(prop->field); /* FIXME */ 317 prop->field = g_strdup((gchar *)field); 318 314 319 prop->tablefield = g_strjoin(".", table, field, NULL); 315 320 } … … 366 371 gchar *property = (gchar *) key; 367 372 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); 368 388 369 389 if(_cont->elts == 0) … … 387 407 cont->string = _sql; 388 408 cont->elts = 0; 409 cont->type = type_attr; 389 410 390 411 g_hash_table_foreach (type_attr->prophash, __build_static_sql, cont); 391 412 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 419 static 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 436 static 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 445 void 446 midgard_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 2924 2924 MIDGARD_ERRNO_SET(object->dbpriv->mgd, MGD_ERR_OK); 2925 2925 2926 GSList *child s= NULL;2927 child s = object->dbpriv->storage_data->childs;2928 2929 if ((childcname == NULL) || (object->dbpriv->storage_data->child s== NULL)) {2926 GSList *children = NULL; 2927 children = object->dbpriv->storage_data->children; 2928 2929 if ((childcname == NULL) || (object->dbpriv->storage_data->children == NULL)) { 2930 2930 MIDGARD_ERRNO_SET(object->dbpriv->mgd, MGD_ERR_NOT_EXISTS); 2931 2931 return NULL; 2932 2932 } 2933 2933 2934 if(!g_slist_find(object->dbpriv->storage_data->child s, (gpointer)g_type_from_name(childcname))) {2934 if(!g_slist_find(object->dbpriv->storage_data->children, (gpointer)g_type_from_name(childcname))) { 2935 2935 MIDGARD_ERRNO_SET(object->dbpriv->mgd, MGD_ERR_NOT_EXISTS); 2936 2936 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, … … 3017 3017 3018 3018 GSList *list = NULL; 3019 GSList *children = self->dbpriv->storage_data->child s; /* FIXME, make it proper English ;) */3019 GSList *children = self->dbpriv->storage_data->children; 3020 3020 3021 3021 for (list = children ; list != NULL; list = list->next) { trunk/midgard/core/midgard/src/midgard_object_class.c
r21903 r22248 144 144 145 145 _GET_TYPE_ATTR(klass); 146 if(!type_attr->child s)146 if(!type_attr->children) 147 147 return NULL; 148 148 149 GSList *slist = type_attr->child s;149 GSList *slist = type_attr->children; 150 150 guint i = 0; 151 151 MidgardObjectClass **children = trunk/midgard/core/midgard/src/schema.h
r22233 r22248 68 68 gchar *primaryfield; 69 69 gboolean use_lang; 70 GSList *child s;70 GSList *children; 71 71 guint property_count; 72 72 gchar *tmp_select; … … 96 96 void midgard_core_schema_type_build_static_sql (MgdSchemaTypeAttr *type_attr); 97 97 void midgard_core_schema_type_initialize_paramspec (MgdSchemaTypeAttr *type); 98 98 void midgard_core_schema_type_validate_fields (MgdSchemaTypeAttr *type); 99 99 100 100 /* RESERVED WORDS */
