source: tags/arb_5.0/ARBDB/adtables.c

Last change on this file was 6143, checked in by westram, 16 years ago
  • backport [6141] (parts changing code, but only strings and comments)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include "adlocal.h"
5/* #include "arbdb.h" */
6#include "arbdbt.h"
7
8
9/* *************** tables, for ARB BIO storage *******************
10
11 *  hierarchical organization:
12
13
14 *  main:
15 *      table_data:
16 *          table:
17 *              name    (indexed by default)
18 *              entries
19 *                  entry
20 *                      name (which is an id)
21 *                      ....
22 *                  entry
23 *                  ...
24 *              fields
25 *                  field
26 *                      name
27 *                      type
28 *                      description
29 *                  field
30 *                  ....
31 *             }
32 *      }
33 */
34
35GBDATA *gbt_table_link_follower(GBDATA *gb_main, GBDATA *gb_link, const char *link) {
36    GBDATA *gb_table;
37    char save;
38    char *sep;
39    GBUSE(gb_main);
40    GBUSE(gb_link);
41    sep = strchr(link,':');
42    if (!sep){
43        GB_export_errorf("Link '%s' is missing second ':' tag", link);
44        return NULL;
45    }
46    save = *sep;
47    *sep = 0;
48    gb_table = GBT_open_table(gb_main,link,1);
49    *sep = save;
50
51    if (!gb_table){
52        GB_export_errorf("Table '%s' does not exist",link);
53        return NULL;
54    }
55    return GBT_find_table_entry(gb_table,sep+1);
56}
57
58GB_ERROR GBT_install_table_link_follower(GBDATA *gb_main){
59    GB_install_link_follower(gb_main,"T",gbt_table_link_follower);
60    return 0;
61}
62
63#ifdef __cplusplus
64extern "C" {
65#endif
66
67    static void g_bt_table_deleted(GBDATA *gb_table,int *clientdata, GB_CB_TYPE gbtype){
68        GB_MAIN_TYPE *Main = gb_get_main_during_cb();
69        GBUSE(gb_table);
70        GBUSE(gbtype);
71        GBUSE(clientdata);
72        GBS_free_hash(Main->table_hash);
73        Main->table_hash = GBS_create_hash(256, GB_MIND_CASE);
74    }
75
76#ifdef __cplusplus
77}
78#endif
79
80GBDATA *GBT_open_table(GBDATA *gb_table_root,const char *table_name, GB_BOOL read_only){
81    /** open a table. This routines is optimized to look for existing tables */
82    GBDATA *gb_table;
83    GBDATA *gb_table_name;
84    GBDATA *gb_table_description;
85    GBDATA *gb_table_data;
86    GBDATA *gb_table_entries;
87    GBDATA *gb_table_fields;
88    GBDATA *gb_table_name_field;
89    GB_MAIN_TYPE *Main = GB_MAIN(gb_table_root);
90    gb_table = (GBDATA *)GBS_read_hash(Main->table_hash,table_name);
91    if (gb_table) return gb_table;
92
93    gb_table_data = GB_search(gb_table_root,"table_data",GB_CREATE_CONTAINER);
94    GB_create_index(gb_table_data,"name",GB_IGNORE_CASE,256);
95
96    gb_table_name = GB_find_string(gb_table_data,"name",table_name,GB_IGNORE_CASE,down_2_level);
97    if (gb_table_name) return GB_get_father(gb_table_name);
98    if (read_only) return NULL;
99
100                /* now lets create the table */
101    gb_table = GB_create_container(gb_table_data,"table");      GB_add_callback(gb_table,GB_CB_DELETE,g_bt_table_deleted,0);
102    gb_table_name = GB_create(gb_table,"name",GB_STRING);
103    gb_table_description = GB_create(gb_table,"description",GB_STRING);
104    GB_write_string(gb_table_name,table_name);          GB_write_security_levels(gb_table_name,0,7,7); /* nether delete or change the name */
105    GB_write_string(gb_table_description,"No description");
106    gb_table_entries = GB_create_container(gb_table,"entries"); GB_write_security_levels(gb_table_entries,0,0,7); /* nether delete this */
107    gb_table_fields = GB_create_container(gb_table,"fields");   GB_write_security_levels(gb_table_fields,0,0,7); /* nether intended to be deleted */
108    gb_table_name_field = GBT_open_table_field(gb_table,"name",GB_STRING); /* for the id */
109    GB_write_security_levels(gb_table_name_field,0,0,7); /* Never delete name field */
110    return gb_table;
111}
112
113GBDATA *GBT_first_table(GBDATA *gb_main){
114    GBDATA *gb_table_data;
115    GBDATA *gb_table;
116    gb_table_data = GB_search(gb_main,"table_data",GB_CREATE_CONTAINER);
117    GB_create_index(gb_table_data,"name",GB_IGNORE_CASE,256);
118    gb_table = GB_entry(gb_table_data,"table");
119    return gb_table;
120}
121
122GBDATA *GBT_next_table(GBDATA *gb_table){
123    gb_assert(GB_has_key(gb_table, "table"));
124    return GB_nextEntry(gb_table);
125}
126
127
128
129GBDATA *GBT_first_table_entry(GBDATA *gb_table){
130    GBDATA *gb_entries = GB_entry(gb_table,"entries");
131    return GB_entry(gb_entries,"entry");
132}
133
134GBDATA *GBT_first_marked_table_entry(GBDATA *gb_table){
135    GBDATA *gb_entries = GB_entry(gb_table,"entries");
136    return GB_first_marked(gb_entries,"entry");
137}
138
139GBDATA *GBT_next_table_entry(GBDATA *gb_table_entry){
140    gb_assert(GB_has_key(gb_table_entry, "entry"));
141    return GB_nextEntry(gb_table_entry);
142}
143
144GBDATA *GBT_next_marked_table_entry(GBDATA *gb_table_entry){
145    return GB_next_marked(gb_table_entry,"entry");
146}
147
148GBDATA *GBT_find_table_entry(GBDATA *gb_table,const char *id){
149    GBDATA *gb_entries = GB_entry(gb_table,"entries");
150    GBDATA *gb_entry_name = GB_find_string(gb_entries,"name",id,GB_IGNORE_CASE,down_2_level);
151    if (!gb_entry_name) return NULL;
152    return GB_get_father(gb_entry_name);
153}
154
155GBDATA *GBT_open_table_entry(GBDATA *gb_table, const char *id){
156    GBDATA *gb_entries = GB_entry(gb_table,"entries");
157    GBDATA *gb_entry_name = GB_find_string(gb_entries,"name",id,GB_IGNORE_CASE,down_2_level);
158    GBDATA *gb_entry;
159    if (gb_entry_name) GB_get_father(gb_entry_name);
160    gb_entry = GB_create_container(gb_entries,"entry");
161    gb_entry_name = GB_create(gb_entry,"name",GB_STRING);
162    GB_write_string(gb_entry_name,id);
163    return gb_entry;
164}
165
166GBDATA *GBT_first_table_field(GBDATA *gb_table){
167    GBDATA *gb_fields = GB_entry(gb_table,"fields");
168    return GB_entry(gb_fields,"field");
169}
170
171GBDATA *GBT_first_marked_table_field(GBDATA *gb_table){
172    GBDATA *gb_fields = GB_entry(gb_table,"fields");
173    return GB_first_marked(gb_fields,"field");
174}
175GBDATA *GBT_next_table_field(GBDATA *gb_table_field){
176    gb_assert(GB_has_key(gb_table_field, "field"));
177    return GB_nextEntry(gb_table_field);
178}
179
180GBDATA *GBT_next_marked_table_field(GBDATA *gb_table_field){
181    return GB_next_marked(gb_table_field,"field");
182}
183
184GBDATA *GBT_find_table_field(GBDATA *gb_table,const char *id){
185    GBDATA *gb_fields = GB_entry(gb_table,"fields");
186    GBDATA *gb_field_name = GB_find_string(gb_fields,"name",id,GB_IGNORE_CASE,down_2_level);
187    if (!gb_field_name) return NULL;
188    return GB_get_father(gb_field_name);
189}
190
191GB_TYPES GBT_get_type_of_table_entry_field(GBDATA *gb_table,const char *fieldname){
192    GBDATA *gb_fields = GB_entry(gb_table,"fields");
193    GBDATA *gb_field_name = GB_find_string(gb_fields,"name",fieldname,GB_IGNORE_CASE,down_2_level);
194    GBDATA *gb_field_type;
195    if (!gb_field_name) return GB_NONE;
196    gb_field_type = GB_entry(gb_field_name,"type");
197    return (GB_TYPES) GB_read_int(gb_field_type);
198}
199
200GB_ERROR GBT_savely_write_table_entry_field(GBDATA *gb_table,GBDATA *gb_entry, const char *fieldname,const char *value_in_ascii_format){
201    GBDATA *gb_entry_field;
202    GB_TYPES type = GBT_get_type_of_table_entry_field(gb_table,fieldname);
203    if (type == GB_NONE){
204        return GB_export_errorf("There is no field description '%s' for your table", fieldname);
205    }
206    gb_entry_field = GB_search(gb_entry,"fieldname",type);
207    return GB_write_as_string(gb_entry_field,value_in_ascii_format);
208}
209
210GBDATA *GBT_open_table_field(GBDATA *gb_table, const char *fieldname, GB_TYPES type_of_field){
211    GBDATA *gb_table_field = GBT_find_table_field(gb_table, fieldname);
212    GBDATA *gb_table_field_name;
213    GBDATA *gb_table_field_type;
214    GBDATA *gb_table_field_description;
215    GBDATA *gb_fields;
216    if (gb_table_field) return gb_table_field;
217
218    gb_fields = GB_entry(gb_table,"fields");
219    gb_table_field = GB_create_container(gb_fields,"field");
220    gb_table_field_name = GB_create(gb_table_field,"name",GB_STRING);
221    GB_write_string(gb_table_field_name,fieldname); GB_write_security_levels(gb_table_field_name,0,7,7); /* never change this */
222    gb_table_field_type = GB_create(gb_table_field,"type",GB_INT);
223    GB_write_int(gb_table_field_type,type_of_field);    GB_write_security_levels(gb_table_field_type,0,7,7);
224    gb_table_field_description = GB_create(gb_table_field,"description",GB_STRING);
225    GB_write_string(gb_table_field_description,"No description yet");
226    return gb_table_field;
227}
228
Note: See TracBrowser for help on using the repository browser.