use configured root node from PgRepository in pg vfs/webdav webdav

Sun, 14 Aug 2022 11:40:54 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 14 Aug 2022 11:40:54 +0200
branch
webdav
changeset 374
77506ec632a4
parent 373
f78a585e1a2f
child 375
32b8017f5308

use configured root node from PgRepository in pg vfs/webdav

src/server/plugins/postgresql/config.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/config.h file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/pgtest.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/pgtest.h file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/vfs.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/vfs.h file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/webdav.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/webdav.h file | annotate | diff | comparison | revisions
--- 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) {
--- 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
--- 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) {
--- 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);
--- 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;
     }
     
--- 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 <libpq-fe.h>
 #include <libpq/libpq-fs.h>
 
@@ -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,
--- 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
--- 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 <libpq-fe.h>
 #include <ucx/buffer.h>
 
@@ -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);
 

mercurial