# HG changeset patch # User Olaf Wintermann # Date 1660470054 -7200 # Node ID 77506ec632a48f1243866a2b7f466928a9f7d97d # Parent f78a585e1a2fb700ea5d4b0c6f940b43a504f8ed use configured root node from PgRepository in pg vfs/webdav diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/config.c --- a/src/server/plugins/postgresql/config.c Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/config.c Sun Aug 14 11:40:54 2022 +0200 @@ -48,7 +48,7 @@ // if the lookup succeeds, the resource id is written to rootid // in case of an error, an error message will be logged // returns: 0 success, 1 error -static int pg_lookup_root(ResourceData *res, scstr_t rootnode, int64_t *rootid) { +int pg_lookup_root(ResourceData *res, const char *rootnode, int64_t *rootid) { PGconn *connection = res->data; PGresult *result = PQexecParams( @@ -56,7 +56,7 @@ sql_get_repository_root, 1, // number of parameters NULL, - &rootnode.ptr, // parameter value + &rootnode, // parameter value NULL, NULL, 0); // 0: result in text format @@ -73,12 +73,12 @@ char *resource_id_str = PQgetvalue(result, 0, 0); if(resource_id_str) { if(!util_strtoint(resource_id_str, rootid)) { - log_ereport(LOG_FAILURE, "pg: unexpected result for column resource_id", rootnode.ptr); + log_ereport(LOG_FAILURE, "pg: unexpected result for column resource_id", rootnode); ret = 1; } } } else { - log_ereport(LOG_FAILURE, "pg: cannot find root resource '%s'", rootnode.ptr); + log_ereport(LOG_FAILURE, "pg: cannot find root resource '%s'", rootnode); ret = 1; } PQclear(result); @@ -128,7 +128,7 @@ return NULL; } // do lookup, if successful, root_id will be set - int lookup_err = pg_lookup_root(res, cfg_rootnode, &root_id); + int lookup_err = pg_lookup_root(res, cfg_rootnode.ptr, &root_id); // we don't need the connection anymore resourcepool_free(NULL, NULL, res); if(lookup_err) { diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/config.h --- a/src/server/plugins/postgresql/config.h Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/config.h Sun Aug 14 11:40:54 2022 +0200 @@ -71,6 +71,8 @@ UcxList *tables; } PgExtParser; +int pg_lookup_root(ResourceData *res, const char *rootnode, int64_t *rootid); + PgRepository* pg_init_repo(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config); #ifdef __cplusplus diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/pgtest.c --- a/src/server/plugins/postgresql/pgtest.c Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/pgtest.c Sun Aug 14 11:40:54 2022 +0200 @@ -52,6 +52,7 @@ static int abort_pg_tests = 0; static PGconn *test_connection; static ResourceData resdata; +static PgRepository test_repo; void debug_print_resources(void) { PGresult *result = PQexec(test_connection, "select * from Resource;"); @@ -67,6 +68,17 @@ printf("\n"); } +static void test_root_lookup(void) { + memset(&test_repo, 0, sizeof(PgRepository)); + + int64_t root_id = -1; + int err = pg_lookup_root(&resdata, "root", &root_id); + test_repo.root_resource_id = root_id; + + if(err || root_id < 0) { + abort_pg_tests = 1; + } +} void register_pg_tests(int argc, char **argv, UcxTestSuite *suite) { @@ -79,9 +91,12 @@ abort_pg_tests = 1; } + resdata.data = test_connection; + test_root_lookup(); + ucx_test_register(suite, test_pg_conn); if(!abort_pg_tests) { - resdata.data = test_connection; + ucx_test_register(suite, test_pg_lookup_root); ucx_test_register(suite, test_pg_vfs_open); ucx_test_register(suite, test_pg_vfs_io); @@ -230,9 +245,18 @@ UCX_TEST_END; } +UCX_TEST(test_pg_lookup_root) { + UCX_TEST_BEGIN; + + // test already done in test_root_lookup() + UCX_TEST_ASSERT(!abort_pg_tests, "Lookup failed"); + + UCX_TEST_END; +} -static VFS* create_test_pgvfs(Session *sn, Request *rq) { - return pg_vfs_create_from_resourcedata(sn, rq, &resdata); + +static VFS* create_test_pgvfs(Session *sn, Request *rq) { + return pg_vfs_create_from_resourcedata(sn, rq, &test_repo, &resdata); } @@ -481,7 +505,7 @@ static WebdavBackend* create_test_pgdav(Session *sn, Request *rq) { - return pg_webdav_create_from_resdata(sn, rq, &resdata); + return pg_webdav_create_from_resdata(sn, rq, &test_repo, &resdata); } UCX_TEST(test_pg_webdav_create_from_resdata) { diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/pgtest.h --- a/src/server/plugins/postgresql/pgtest.h Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/pgtest.h Sun Aug 14 11:40:54 2022 +0200 @@ -48,6 +48,8 @@ UCX_TEST(test_pg_conn); +UCX_TEST(test_pg_lookup_root); + UCX_TEST(test_pg_vfs_open); UCX_TEST(test_pg_vfs_io); UCX_TEST(test_pg_vfs_stat); diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/vfs.c --- a/src/server/plugins/postgresql/vfs.c Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/vfs.c Sun Aug 14 11:40:54 2022 +0200 @@ -83,7 +83,7 @@ regexp_split_to_array($1, '/') as pathelm,\n\ 1 as pathdepth\n\ from Resource\n\ - where parent_id is null\n\ + where resource_id = $2\n\ union\n\ select\n\ r.resource_id,\n\ @@ -106,7 +106,7 @@ // Same as sql_resolve_path, but it returns the root collection // params: $1: path string (should be '/') -static const char *sql_get_root = "select resource_id, parent_id, $1 as fullpath, resoid, true as iscollection, lastmodified, creationdate, contentlength, etag from Resource where parent_id is null;"; +static const char *sql_get_root = "select resource_id, parent_id, $1 as fullpath, resoid, true as iscollection, lastmodified, creationdate, contentlength, etag from Resource where resource_id = $2;"; // Get all children of a specific collection // params: $1: parent resource_id @@ -169,10 +169,10 @@ } // resdata will be freed automatically when the request is finished - return pg_vfs_create_from_resourcedata(sn, rq, resdata); + return pg_vfs_create_from_resourcedata(sn, rq, repo, resdata); } -VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, ResourceData *resdata) { +VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, PgRepository *repo, ResourceData *resdata) { // Create a new VFS object and a separate instance object // VFS contains fptrs that can be copied from pg_vfs_class // instance contains request specific data (PGconn) @@ -188,6 +188,8 @@ } vfs_priv->connection = resdata->data; vfs_priv->pg_resource = resdata; + vfs_priv->root_resource_id = repo->root_resource_id; + snprintf(vfs_priv->root_resource_id_str, 32, "%" PRId64, repo->root_resource_id); memcpy(vfs, &pg_vfs_class, sizeof(VFS)); vfs->flags = 0; @@ -200,6 +202,7 @@ int pg_resolve_path( PGconn *connection, const char *path, + const char *root_id, int64_t *parent_id, int64_t *resource_id, Oid *oid, @@ -228,13 +231,14 @@ // get last node of path *resource_name = util_resource_name(path); - const char *sql = pathlen == 1 ? sql_get_root : sql_resolve_path; + const char *sql = pathlen == 1 ? sql_get_root : sql_resolve_path; + const char* params[2] = { path, root_id }; PGresult *result = PQexecParams( connection, sql, - 1, // number of parameters + 2, // number of parameters NULL, - &path, // parameter value + params, // parameter value NULL, NULL, 0); // 0: result in text format @@ -463,7 +467,18 @@ WSBool iscollection; Oid unused_oid = 0; - int err = pg_resolve_path(pg->connection, parent_path, &parent_id, &resource_id, &unused_oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno); + int err = pg_resolve_path( + pg->connection, + parent_path, + pg->root_resource_id_str, + &parent_id, + &resource_id, + &unused_oid, + &resname, + &iscollection, + NULL, + NULL, + &ctx->vfs_errno); FREE(parent_path); if(err) { ctx->vfs_errno = ENOENT; @@ -589,7 +604,7 @@ struct stat s; char etag[PG_ETAG_MAXLEN]; Oid oid = 0; - if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, etag, &ctx->vfs_errno)) { + if(pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, etag, &ctx->vfs_errno)) { if((oflags & O_CREAT) == O_CREAT) { if(pg_create_file(ctx, pg, path, &resource_id, &parent_id, &oid, &resname, &s, FALSE)) { return NULL; @@ -664,7 +679,7 @@ int64_t parent_id, resource_id; const char *resname; WSBool iscollection; - return pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, buf, NULL, &ctx->vfs_errno); + return pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, NULL, &resname, &iscollection, buf, NULL, &ctx->vfs_errno); } int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) { @@ -722,7 +737,7 @@ WSBool iscollection; struct stat s; Oid oid = 0; - if(!pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, NULL, &ctx->vfs_errno)) { + if(!pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, NULL, &ctx->vfs_errno)) { ctx->vfs_errno = EEXIST; return 1; } @@ -744,7 +759,7 @@ parent_id = -1; WSBool iscollection; Oid oid = 0; - if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { + if(pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, &oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { return 1; } @@ -765,7 +780,7 @@ resource_id = -1; parent_id = -1; WSBool iscollection; - if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { + if(pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, NULL, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { return 1; } diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/vfs.h --- a/src/server/plugins/postgresql/vfs.h Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/vfs.h Sun Aug 14 11:40:54 2022 +0200 @@ -32,6 +32,8 @@ #include "../../public/nsapi.h" #include "../../public/vfs.h" +#include "config.h" + #include #include @@ -44,6 +46,7 @@ typedef struct PgVFS { ResourceData *pg_resource; PGconn *connection; + char root_resource_id_str[32]; int64_t root_resource_id; } PgVFS; @@ -69,7 +72,7 @@ VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb, void *initData); -VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, ResourceData *resdata); +VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, PgRepository *repo, ResourceData *resdata); /* @@ -82,6 +85,7 @@ int pg_resolve_path( PGconn *connection, const char *path, + const char *root_id, int64_t *parent_id, int64_t *resource_id, Oid *oid, diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/webdav.c --- a/src/server/plugins/postgresql/webdav.c Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/webdav.c Sun Aug 14 11:40:54 2022 +0200 @@ -296,10 +296,10 @@ return NULL; } - return pg_webdav_create_from_resdata(sn, rq, resdata); + return pg_webdav_create_from_resdata(sn, rq, repo, resdata); } -WebdavBackend* pg_webdav_create_from_resdata(Session *sn, Request *rq, ResourceData *resdata) { +WebdavBackend* pg_webdav_create_from_resdata(Session *sn, Request *rq, PgRepository *repo, ResourceData *resdata) { WebdavBackend *webdav = pool_malloc(sn->pool, sizeof(WebdavBackend)); if(!webdav) { return NULL; @@ -316,6 +316,9 @@ instance->pg_resource = resdata; instance->connection = resdata->data; + instance->repository = repo; + snprintf(instance->root_resource_id_str, 32, "%" PRId64, repo->root_resource_id); + return webdav; } @@ -384,6 +387,7 @@ int err = pg_resolve_path( pgdav->connection, path, + pgdav->root_resource_id_str, &parent_id, &resource_id, NULL, // OID @@ -869,6 +873,7 @@ int err = pg_resolve_path( pgdav->connection, path, + pgdav->root_resource_id_str, &parent_id, &resource_id, NULL, // OID diff -r f78a585e1a2f -r 77506ec632a4 src/server/plugins/postgresql/webdav.h --- a/src/server/plugins/postgresql/webdav.h Sat Aug 13 15:56:51 2022 +0200 +++ b/src/server/plugins/postgresql/webdav.h Sun Aug 14 11:40:54 2022 +0200 @@ -32,6 +32,8 @@ #include "../../public/nsapi.h" #include "../../public/webdav.h" +#include "config.h" + #include #include @@ -44,7 +46,8 @@ typedef struct PgWebdavBackend { ResourceData *pg_resource; PGconn *connection; - int64_t root_resource_id; + PgRepository *repository; + char root_resource_id_str[32]; } PgWebdavBackend; typedef struct PgPropfind { @@ -57,7 +60,7 @@ void* pg_webdav_init(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config); WebdavBackend* pg_webdav_create(Session *sn, Request *rq, pblock *pb, void *initData); -WebdavBackend* pg_webdav_create_from_resdata(Session *sn, Request *rq, ResourceData *resdata); +WebdavBackend* pg_webdav_create_from_resdata(Session *sn, Request *rq, PgRepository *repo, ResourceData *resdata); WebdavBackend* pg_webdav_prop_create(Session *sn, Request *rq, pblock *pb);