28 |
28 |
29 #include "config.h" |
29 #include "config.h" |
30 |
30 |
31 #include "../../util/util.h" |
31 #include "../../util/util.h" |
32 |
32 |
33 PgRepository* pg_init_repo(pool_handle_t *pool, WSConfigNode *config) { |
33 static const char *sql_get_repository_root = "select resource_id from Resource where parent_id is NULL and nodename = $1 ;"; |
|
34 |
|
35 |
|
36 // Uses a PGconn to lookup the resource id of the specified root node |
|
37 // if the lookup succeeds, the resource id is written to rootid |
|
38 // in case of an error, an error message will be logged |
|
39 // returns: 0 success, 1 error |
|
40 static int pg_lookup_root(ResourceData *res, scstr_t rootnode, int64_t *rootid) { |
|
41 PGconn *connection = res->data; |
|
42 |
|
43 PGresult *result = PQexecParams( |
|
44 connection, |
|
45 sql_get_repository_root, |
|
46 1, // number of parameters |
|
47 NULL, |
|
48 &rootnode.ptr, // parameter value |
|
49 NULL, |
|
50 NULL, |
|
51 0); // 0: result in text format |
|
52 |
|
53 if(!result) { |
|
54 log_ereport(LOG_FAILURE, "pg: root lookup failed: %s", PQerrorMessage(connection)); |
|
55 return 1; |
|
56 } |
|
57 |
|
58 int ret = 0; |
|
59 |
|
60 int nrows = PQntuples(result); |
|
61 if(nrows == 1) { |
|
62 char *resource_id_str = PQgetvalue(result, 0, 0); |
|
63 if(resource_id_str) { |
|
64 if(!util_strtoint(resource_id_str, rootid)) { |
|
65 log_ereport(LOG_FAILURE, "pg: unexpected result for column resource_id", rootnode.ptr); |
|
66 ret = 1; |
|
67 } |
|
68 } |
|
69 } else { |
|
70 log_ereport(LOG_FAILURE, "pg: cannot find root resource '%s'", rootnode.ptr); |
|
71 ret = 1; |
|
72 } |
|
73 PQclear(result); |
|
74 |
|
75 return ret; |
|
76 } |
|
77 |
|
78 PgRepository* pg_init_repo(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config) { |
34 UcxAllocator a = util_pool_allocator(pool); |
79 UcxAllocator a = util_pool_allocator(pool); |
35 |
80 |
36 ConfigNode *pg = serverconfig_get_node(config, CONFIG_NODE_OBJECT, SC("Postgresql")); |
81 ConfigNode *pg = serverconfig_get_node(config, CONFIG_NODE_OBJECT, SC("Postgresql")); |
37 if(!pg) { |
82 if(!pg) { |
38 log_ereport(LOG_MISCONFIG, "pg_init_repo: missing postgresql config object"); |
83 log_ereport(LOG_MISCONFIG, "pg_init_repo: missing postgresql config object"); |
39 return NULL; |
84 return NULL; |
40 } |
85 } |
41 |
86 |
42 scstr_t cfg_respool = serverconfig_directive_value(pg, SC("ResourcePool")); |
87 scstr_t cfg_respool = serverconfig_directive_value(pg, SC("ResourcePool")); |
43 scstr_t cfg_rootid = serverconfig_directive_value(pg, SC("RootId")); |
88 scstr_t cfg_rootid = serverconfig_directive_value(pg, SC("RootId")); |
|
89 scstr_t cfg_rootnode = serverconfig_directive_value(pg, SC("RootNode")); |
44 scstr_t cfg_dav = serverconfig_directive_value(pg, SC("PGDavConfig")); |
90 scstr_t cfg_dav = serverconfig_directive_value(pg, SC("PGDavConfig")); |
45 |
91 |
46 // minimum requirement is a resource pool |
92 // minimum requirement is a resource pool |
47 if(cfg_respool.length == 0) { |
93 if(cfg_respool.length == 0) { |
48 return NULL; |
94 return NULL; |
55 log_ereport(LOG_MISCONFIG, "pg_init_repo: RootId parameter is not an integer: %s", cfg_rootid.ptr); |
101 log_ereport(LOG_MISCONFIG, "pg_init_repo: RootId parameter is not an integer: %s", cfg_rootid.ptr); |
56 return NULL; |
102 return NULL; |
57 } |
103 } |
58 } |
104 } |
59 |
105 |
|
106 // warn if RootId and RootNode are specified |
|
107 if(cfg_rootid.length > 0 && cfg_rootnode.length > 0) { |
|
108 log_ereport(LOG_WARN, "log_init_repo: RootId and RootNode specified, RootNode ignored"); |
|
109 } else if(cfg_rootnode.length > 0) { |
|
110 // check root node |
|
111 |
|
112 // resolve rootnode |
|
113 // therefore we first need to get a connection from the resourcepool |
|
114 ResourceData *res = resourcepool_cfg_lookup(cfg, cfg_respool.ptr, 0); |
|
115 if(!res) { |
|
116 log_ereport(LOG_MISCONFIG, "pg_init_repo: resource lookup failed"); |
|
117 return NULL; |
|
118 } |
|
119 // do lookup, if successful, root_id will be set |
|
120 int lookup_err = pg_lookup_root(res, cfg_rootnode, &root_id); |
|
121 // we don't need the connection anymore |
|
122 resourcepool_free(NULL, NULL, res); |
|
123 if(lookup_err) { |
|
124 // no logging required, pg_lookup_root will log the error |
|
125 return NULL; |
|
126 } |
|
127 } |
|
128 |
60 PgRepository *repo = pool_malloc(pool, sizeof(PgRepository)); |
129 PgRepository *repo = pool_malloc(pool, sizeof(PgRepository)); |
61 ZERO(repo, sizeof(PgRepository)); |
130 ZERO(repo, sizeof(PgRepository)); |
62 |
131 |
63 repo->resourcepool = sstrdup_a(&a, cfg_respool); |
132 repo->resourcepool = sstrdup_a(&a, cfg_respool); |
64 |
133 |