source: tags/ms_r16q3/ARBDB/adtables.cxx

Last change on this file was 11043, checked in by westram, 10 years ago
  • use typed DB callbacks (ARBDB)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : adtables.cxx                                      //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <arbdbt.h>
12#include <ad_cb.h>
13
14#include "gb_main.h"
15#include "gb_data.h"
16
17
18/* *************** tables, for ARB BIO storage *******************
19
20 *  hierarchical organization:
21
22
23 *  main:
24 *      table_data:
25 *          table:
26 *              name    (indexed by default)
27 *              entries
28 *                  entry
29 *                      name (which is an id)
30 *                      ....
31 *                  entry
32 *                  ...
33 *              fields
34 *                  field
35 *                      name
36 *                      type
37 *                      description
38 *                  field
39 *                  ....
40 *             }
41 *      }
42 */
43
44static GBDATA *GBT_find_table_entry(GBDATA *gb_table, const char *id) {
45    GBDATA *gb_entries = GB_entry(gb_table, "entries");
46    GBDATA *gb_entry_name = GB_find_string(gb_entries, "name", id, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
47    if (!gb_entry_name) return NULL;
48    return GB_get_father(gb_entry_name);
49}
50
51static GBDATA *gbt_table_link_follower(GBDATA *gb_main, GBDATA */*gb_link*/, const char *link) {
52    GBDATA *gb_table;
53    char save;
54    char *sep;
55    // GBUSE(gb_main);
56    // GBUSE(gb_link);
57    sep = const_cast<char*>(strchr(link, ':'));
58    if (!sep) {
59        GB_export_errorf("Link '%s' is missing second ':' tag", link);
60        return NULL;
61    }
62    save = *sep;
63    *sep = 0;
64    gb_table = GBT_open_table(gb_main, link, 1);
65    *sep = save;
66
67    if (!gb_table) {
68        GB_export_errorf("Table '%s' does not exist", link);
69        return NULL;
70    }
71    return GBT_find_table_entry(gb_table, sep+1);
72}
73
74GB_ERROR GBT_install_table_link_follower(GBDATA *gb_main) {
75    GB_install_link_follower(gb_main, "T", gbt_table_link_follower);
76    return 0;
77}
78
79static void g_bt_table_deleted() {
80    GB_MAIN_TYPE *Main = gb_get_main_during_cb();
81    GBS_free_hash(Main->table_hash);
82    Main->table_hash = GBS_create_hash(256, GB_MIND_CASE);
83}
84
85GBDATA *GBT_open_table(GBDATA *gb_table_root, const char *table_name, bool read_only) {
86    // open a table. This routines is optimized to look for existing tables
87    GBDATA *gb_table;
88    GBDATA *gb_table_name;
89    GBDATA *gb_table_description;
90    GBDATA *gb_table_data;
91    GBDATA *gb_table_entries;
92    GBDATA *gb_table_fields;
93    GBDATA *gb_table_name_field;
94
95    GB_MAIN_TYPE *Main = GB_MAIN(gb_table_root);
96    gb_table           = (GBDATA *)GBS_read_hash(Main->table_hash, table_name);
97    if (gb_table) return gb_table;
98
99    gb_table_data = GB_search(gb_table_root, "table_data", GB_CREATE_CONTAINER);
100    ASSERT_NO_ERROR(GB_create_index(gb_table_data, "name", GB_IGNORE_CASE, 256));
101
102    gb_table_name = GB_find_string(gb_table_data, "name", table_name, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
103    if (gb_table_name) return GB_get_father(gb_table_name);
104    if (read_only) return NULL;
105
106    // now lets create the table
107    gb_table = GB_create_container(gb_table_data, "table");
108    GB_add_callback(gb_table, GB_CB_DELETE, makeDatabaseCallback(g_bt_table_deleted));
109
110    gb_table_name = GB_create(gb_table, "name", GB_STRING);
111    GB_write_string(gb_table_name, table_name);
112    GB_write_security_levels(gb_table_name, 0, 7, 7); // neither delete nor change the name
113
114    gb_table_description = GB_create(gb_table, "description", GB_STRING);
115    GB_write_string(gb_table_description, "No description");
116
117    gb_table_entries = GB_create_container(gb_table, "entries");
118    GB_write_security_levels(gb_table_entries, 0, 0, 7); // never delete this
119
120    gb_table_fields = GB_create_container(gb_table, "fields");
121    GB_write_security_levels(gb_table_fields, 0, 0, 7); // not intended to be deleted
122
123    gb_table_name_field = GBT_open_table_field(gb_table, "name", GB_STRING); // for the id
124    GB_write_security_levels(gb_table_name_field, 0, 0, 7); // never delete name field
125
126    return gb_table;
127}
128
129GBDATA *GBT_first_table(GBDATA *gb_main) {
130    GBDATA *gb_table_data;
131    GBDATA *gb_table;
132    gb_table_data = GB_search(gb_main, "table_data", GB_CREATE_CONTAINER);
133    ASSERT_NO_ERROR(GB_create_index(gb_table_data, "name", GB_IGNORE_CASE, 256));
134    gb_table = GB_entry(gb_table_data, "table");
135    return gb_table;
136}
137
138GBDATA *GBT_next_table(GBDATA *gb_table) {
139    gb_assert(GB_has_key(gb_table, "table"));
140    return GB_nextEntry(gb_table);
141}
142
143
144
145GBDATA *GBT_first_table_entry(GBDATA *gb_table) {
146    GBDATA *gb_entries = GB_entry(gb_table, "entries");
147    return GB_entry(gb_entries, "entry");
148}
149
150GBDATA *GBT_next_table_entry(GBDATA *gb_table_entry) {
151    gb_assert(GB_has_key(gb_table_entry, "entry"));
152    return GB_nextEntry(gb_table_entry);
153}
154
155GBDATA *GBT_first_table_field(GBDATA *gb_table) {
156    GBDATA *gb_fields = GB_entry(gb_table, "fields");
157    return GB_entry(gb_fields, "field");
158}
159
160GBDATA *GBT_next_table_field(GBDATA *gb_table_field) {
161    gb_assert(GB_has_key(gb_table_field, "field"));
162    return GB_nextEntry(gb_table_field);
163}
164
165GBDATA *GBT_find_table_field(GBDATA *gb_table, const char *id) {
166    GBDATA *gb_fields = GB_entry(gb_table, "fields");
167    GBDATA *gb_field_name = GB_find_string(gb_fields, "name", id, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
168    if (!gb_field_name) return NULL;
169    return GB_get_father(gb_field_name);
170}
171
172GBDATA *GBT_open_table_field(GBDATA *gb_table, const char *fieldname, GB_TYPES type_of_field) {
173    GBDATA *gb_table_field = GBT_find_table_field(gb_table, fieldname);
174    GBDATA *gb_table_field_name;
175    GBDATA *gb_table_field_type;
176    GBDATA *gb_table_field_description;
177    GBDATA *gb_fields;
178
179    if (gb_table_field) return gb_table_field;
180
181    gb_fields           = GB_entry(gb_table, "fields");
182    gb_table_field      = GB_create_container(gb_fields, "field");
183    gb_table_field_name = GB_create(gb_table_field, "name", GB_STRING);
184
185    GB_write_string(gb_table_field_name, fieldname);
186    GB_write_security_levels(gb_table_field_name, 0, 7, 7); // never change this
187
188    gb_table_field_type = GB_create(gb_table_field, "type", GB_INT);
189
190    GB_write_int(gb_table_field_type, type_of_field);
191    GB_write_security_levels(gb_table_field_type, 0, 7, 7);
192
193    gb_table_field_description = GB_create(gb_table_field, "description", GB_STRING);
194    GB_write_string(gb_table_field_description, "No description yet");
195
196    return gb_table_field;
197}
198
Note: See TracBrowser for help on using the repository browser.