85 |
85 |
86 return ret; |
86 return ret; |
87 } |
87 } |
88 |
88 |
89 PgRepository* pg_init_repo(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) { |
89 PgRepository* pg_init_repo(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) { |
90 UcxAllocator a = util_pool_allocator(pool); |
90 CxAllocator *a = pool_allocator(pool); |
91 |
91 |
92 ConfigNode *pg = serverconfig_get_node(config, CONFIG_NODE_OBJECT, SC("Postgresql")); |
92 ConfigNode *pg = serverconfig_get_node(config, CONFIG_NODE_OBJECT, cx_str("Postgresql")); |
93 if(!pg) { |
93 if(!pg) { |
94 log_ereport(LOG_MISCONFIG, "pg_init_repo: missing postgresql config object"); |
94 log_ereport(LOG_MISCONFIG, "pg_init_repo: missing postgresql config object"); |
95 return NULL; |
95 return NULL; |
96 } |
96 } |
97 |
97 |
98 scstr_t cfg_respool = serverconfig_directive_value(pg, SC("ResourcePool")); |
98 cxstring cfg_respool = serverconfig_directive_value(pg, cx_str("ResourcePool")); |
99 scstr_t cfg_rootid = serverconfig_directive_value(pg, SC("RootId")); |
99 cxstring cfg_rootid = serverconfig_directive_value(pg, cx_str("RootId")); |
100 scstr_t cfg_rootnode = serverconfig_directive_value(pg, SC("RootNode")); |
100 cxstring cfg_rootnode = serverconfig_directive_value(pg, cx_str("RootNode")); |
101 scstr_t cfg_dav = serverconfig_directive_value(pg, SC("PGDavConfig")); |
101 cxstring cfg_dav = serverconfig_directive_value(pg, cx_str("PGDavConfig")); |
102 |
102 |
103 // minimum requirement is a resource pool |
103 // minimum requirement is a resource pool |
104 if(cfg_respool.length == 0) { |
104 if(cfg_respool.length == 0) { |
105 return NULL; |
105 return NULL; |
106 } |
106 } |
138 } |
138 } |
139 |
139 |
140 PgRepository *repo = pool_malloc(pool, sizeof(PgRepository)); |
140 PgRepository *repo = pool_malloc(pool, sizeof(PgRepository)); |
141 ZERO(repo, sizeof(PgRepository)); |
141 ZERO(repo, sizeof(PgRepository)); |
142 |
142 |
143 repo->resourcepool = sstrdup_a(&a, cfg_respool); |
143 repo->resourcepool = cx_strdup_a(a, cfg_respool); |
144 repo->root_resource_id = root_id; |
144 repo->root_resource_id = root_id; |
145 |
145 |
146 // check for extended pg dav config |
146 // check for extended pg dav config |
147 if(cfg_dav.length > 0) { |
147 if(cfg_dav.length > 0) { |
148 // load extended config from config file |
148 // load extended config from config file |
186 ServerConfiguration *cfg, |
186 ServerConfiguration *cfg, |
187 pool_handle_t *pool, |
187 pool_handle_t *pool, |
188 PgRepository *repo, |
188 PgRepository *repo, |
189 const char *file_path) |
189 const char *file_path) |
190 { |
190 { |
191 UcxAllocator a = util_pool_allocator(pool); |
191 CxAllocator *a = pool_allocator(pool); |
192 |
192 |
193 // check if the file exists and can be accessed |
193 // check if the file exists and can be accessed |
194 struct stat s; |
194 struct stat s; |
195 if(stat(file_path, &s)) { |
195 if(stat(file_path, &s)) { |
196 if(errno == ENOENT) { |
196 if(errno == ENOENT) { |
243 { |
243 { |
244 xmlNode *node = root->children; |
244 xmlNode *node = root->children; |
245 int ret = 0; |
245 int ret = 0; |
246 |
246 |
247 PgExtParser parserData; |
247 PgExtParser parserData; |
248 parserData.table_lookup = ucx_map_new(8); |
248 parserData.table_lookup = cxHashMapCreate(cxDefaultAllocator, 8); |
249 parserData.tables = NULL; |
249 parserData.tables = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_ptr, sizeof(PgExtTable)); |
250 |
250 |
251 while(node && !ret) { |
251 while(node && !ret) { |
252 // currently, the only possible config element is <extension> |
252 // currently, the only possible config element is <extension> |
253 if(node->type == XML_ELEMENT_NODE) { |
253 if(node->type == XML_ELEMENT_NODE) { |
254 if(xstreq(node->name, "extension")) { |
254 if(xstreq(node->name, "extension")) { |
258 node = node->next; |
258 node = node->next; |
259 } |
259 } |
260 |
260 |
261 // convert parserData |
261 // convert parserData |
262 if(!ret) { |
262 if(!ret) { |
263 size_t ntables = ucx_list_size(parserData.tables); |
263 size_t ntables = parserData.tables->size; |
264 repo->ntables = ntables; |
264 repo->ntables = ntables; |
265 repo->tables = pool_calloc(pool, ntables, sizeof(PgExtTable)); |
265 repo->tables = pool_calloc(pool, ntables, sizeof(PgExtTable)); |
266 if(repo->tables) { |
266 if(repo->tables) { |
267 int i = 0; |
267 int i = 0; |
268 UCX_FOREACH(elm, parserData.tables) { |
268 CxIterator iter = cxListIterator(parserData.tables, 0); |
269 PgExtTable *tab = elm->data; |
269 cx_foreach(PgExtTable *, tab, iter) { |
270 repo->tables[i++] = *tab; |
270 repo->tables[i++] = *tab; |
271 } |
271 } |
272 } else { |
272 } else { |
273 ret = 1; |
273 ret = 1; |
274 } |
274 } |
275 |
275 |
276 } |
276 } |
277 |
277 |
278 // cleanup parser |
278 // cleanup parser |
279 ucx_list_free_content(parserData.tables, free); |
279 cxListDestroy(parserData.tables); |
280 ucx_list_free(parserData.tables); |
280 cxMapDestroy(parserData.table_lookup); |
281 ucx_map_free(parserData.table_lookup); |
|
282 |
281 |
283 return ret; |
282 return ret; |
284 } |
283 } |
285 |
284 |
286 static int pg_ext_get_extension( |
285 static int pg_ext_get_extension( |
288 pool_handle_t *pool, |
287 pool_handle_t *pool, |
289 PgRepository *repo, |
288 PgRepository *repo, |
290 const char *file_path, |
289 const char *file_path, |
291 xmlNode *ext_node) |
290 xmlNode *ext_node) |
292 { |
291 { |
293 UcxAllocator a = util_pool_allocator(pool); |
292 CxAllocator *a = pool_allocator(pool); |
294 |
293 |
295 xmlNode *node = ext_node->children; |
294 xmlNode *node = ext_node->children; |
296 |
295 |
297 const char *table = NULL; |
296 const char *table = NULL; |
298 UcxList *properties = NULL; |
297 CxList *properties = cxPointerLinkedListCreate(a, cx_cmp_ptr); |
299 |
298 |
300 while(node) { |
299 while(node) { |
301 if(node->type == XML_ELEMENT_NODE) { |
300 if(node->type == XML_ELEMENT_NODE) { |
302 if(xstreq(node->name, "table")) { |
301 if(xstreq(node->name, "table")) { |
303 const char *value = pg_util_xml_get_text(node); |
302 const char *value = pg_util_xml_get_text(node); |
343 log_ereport(LOG_MISCONFIG, "pg: config %s: no properties configured for extension", file_path); |
342 log_ereport(LOG_MISCONFIG, "pg: config %s: no properties configured for extension", file_path); |
344 return 1; |
343 return 1; |
345 } |
344 } |
346 |
345 |
347 // check if the table was already specified |
346 // check if the table was already specified |
348 if(ucx_map_cstr_get(ext->table_lookup, table)) { |
347 if(cxMapGet(ext->table_lookup, cx_hash_key_str(table))) { |
349 log_ereport(LOG_MISCONFIG, "pg: config %s: extension table %s not unique", file_path, table); |
348 log_ereport(LOG_MISCONFIG, "pg: config %s: extension table %s not unique", file_path, table); |
350 return 1; |
349 return 1; |
351 } |
350 } |
352 // mark table as used |
351 // mark table as used |
353 // tabname will be used later, so ist must be allocated in the pool |
352 // tabname will be used later, so ist must be allocated in the pool |
354 char *tabname = pool_strdup(pool, table); |
353 char *tabname = pool_strdup(pool, table); |
355 if(!tabname) return 1; |
354 if(!tabname) return 1; |
356 |
355 |
357 // exttable is only used temporarily |
356 // exttable is only used temporarily |
358 PgExtTable *exttable = malloc(sizeof(PgExtTable)); |
357 PgExtTable exttable; |
359 if(!exttable) return 1; |
358 exttable.table = tabname; |
360 exttable->table = tabname; |
359 exttable.isused = 0; // not relevant in config |
361 exttable->isused = 0; // not relevant in config |
360 int tableindex = (int)ext->tables->size; |
362 int tableindex = (int)ucx_list_size(ext->tables); |
361 cxListAdd(ext->tables, &exttable); |
363 ext->tables = ucx_list_append(ext->tables, exttable); |
362 |
364 |
363 if(cxMapPut(ext->table_lookup, cx_hash_key_str(table), (void*)table)) { |
365 if(ucx_map_cstr_put(ext->table_lookup, table, table)) { |
|
366 return 1; |
364 return 1; |
367 } |
365 } |
368 |
366 |
369 UCX_FOREACH(elm, properties) { |
367 CxIterator iter = cxListIterator(properties, 0); |
370 xmlNode *ps = elm->data; |
368 cx_foreach(xmlNode *, ps, iter) { |
371 const char *value = pg_util_xml_get_text(ps); |
369 const char *value = pg_util_xml_get_text(ps); |
372 |
370 |
373 PgPropertyStoreExt *ext_col = pool_malloc(pool, sizeof(PgPropertyStoreExt)); |
371 PgPropertyStoreExt *ext_col = pool_malloc(pool, sizeof(PgPropertyStoreExt)); |
374 if(!ext_col) { |
372 if(!ext_col) { |
375 return 1; |
373 return 1; |
380 ext_col->column = pool_strdup(pool, (const char*)value); |
378 ext_col->column = pool_strdup(pool, (const char*)value); |
381 if(!ext_col->ns || !ext_col->name || !ext_col->column) { |
379 if(!ext_col->ns || !ext_col->name || !ext_col->column) { |
382 return 1; |
380 return 1; |
383 } |
381 } |
384 |
382 |
385 UcxKey key = webdav_property_key(ext_col->ns, ext_col->name); |
383 CxHashKey key = webdav_property_key(ext_col->ns, ext_col->name); |
386 int err = ucx_map_put(repo->prop_ext, key, ext_col); |
384 int err = cxMapPut(repo->prop_ext, key, ext_col); |
387 free((void*)key.data); |
385 free(key.data.bytes); |
388 if(err) { |
386 if(err) { |
389 return 1; |
387 return 1; |
390 } |
388 } |
391 } |
389 } |
392 |
390 |