implement pg unlink webdav

Mon, 18 Apr 2022 10:53:13 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 18 Apr 2022 10:53:13 +0200
branch
webdav
changeset 294
277a5896a2ec
parent 293
d3899857a81d
child 295
73a1243fce15

implement pg unlink

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
--- a/src/server/plugins/postgresql/pgtest.c	Sun Apr 17 12:04:41 2022 +0200
+++ b/src/server/plugins/postgresql/pgtest.c	Mon Apr 18 10:53:13 2022 +0200
@@ -64,6 +64,8 @@
         ucx_test_register(suite, test_pg_vfs_open);
         ucx_test_register(suite, test_pg_vfs_io);
         ucx_test_register(suite, test_pg_vfs_stat);
+        ucx_test_register(suite, test_pg_vfs_mkdir);
+        ucx_test_register(suite, test_pg_vfs_unlink);
         
         PGresult *result = PQexec(test_connection, "BEGIN");
         PQclear(result);
@@ -113,6 +115,8 @@
     vfs_close(file);
     
     UCX_TEST_END;
+    
+    testutil_destroy_session(sn);
 }
 
 UCX_TEST(test_pg_vfs_io) {
@@ -161,6 +165,7 @@
     
     UCX_TEST_END;
     
+    testutil_destroy_session(sn);
 }
 
 UCX_TEST(test_pg_vfs_stat) {
@@ -201,8 +206,44 @@
     UCX_TEST_ASSERT(testfail != 0, "stat 3 should fail");
     
     UCX_TEST_END;
+    
+    testutil_destroy_session(sn);
 }
 
 UCX_TEST(test_pg_vfs_mkdir) {
     
 }
+
+UCX_TEST(test_pg_vfs_unlink) {
+    Session *sn = testutil_session();
+    Request *rq = testutil_request(sn->pool, "PUT", "/");
+    rq->vfs = create_test_pgvfs(sn, rq);
+    VFSContext *vfs = vfs_request_context(sn, rq);
+    
+    UCX_TEST_BEGIN;
+    
+    SYS_FILE f1 = vfs_open(vfs, "/test_unlink1", O_WRONLY|O_CREAT);
+    UCX_TEST_ASSERT(f1, "cannot create test file");
+    system_fwrite(f1, "test", 4);
+    
+    PgFile *pgfile = f1->data;
+    Oid oid = pgfile->oid;
+    
+    vfs_close(f1);
+    
+    int r = vfs_unlink(vfs, "/test_unlink1");
+    UCX_TEST_ASSERT(r == 0, "unlink failed");
+    
+    f1 = vfs_open(vfs, "/test_unlink1", O_RDONLY);
+    UCX_TEST_ASSERT(f1 == NULL, "test file not deleted");
+    
+    int pgfd = lo_open(test_connection, oid, INV_READ);
+    UCX_TEST_ASSERT(pgfd < 0, "large object not deleted");
+    
+    r = vfs_unlink(vfs, "/test_unlink1");
+    UCX_TEST_ASSERT(r, "unlink should fail");
+    
+    UCX_TEST_END;
+    
+    testutil_destroy_session(sn);
+}
--- a/src/server/plugins/postgresql/pgtest.h	Sun Apr 17 12:04:41 2022 +0200
+++ b/src/server/plugins/postgresql/pgtest.h	Mon Apr 18 10:53:13 2022 +0200
@@ -26,6 +26,7 @@
 UCX_TEST(test_pg_vfs_io);
 UCX_TEST(test_pg_vfs_stat);
 UCX_TEST(test_pg_vfs_mkdir);
+UCX_TEST(test_pg_vfs_unlink);
 
 #ifdef __cplusplus
 }
--- a/src/server/plugins/postgresql/vfs.c	Sun Apr 17 12:04:41 2022 +0200
+++ b/src/server/plugins/postgresql/vfs.c	Mon Apr 18 10:53:13 2022 +0200
@@ -133,6 +133,10 @@
 //         $2: contentlength
 static const char *sql_update_resource = "update Resource set contentlength = $2, lastmodified = now() where resource_id = $1;";
 
+// Delete a resource
+// params: $1: resource_id
+static const char *sql_delete_res = "delete from Resource where resource_id = $1;";
+
 VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb) {
     // resourcepool is required
     char *resource_pool = pblock_findval("resourcepool", pb);
@@ -460,6 +464,37 @@
     return ret;
 }
 
+int pg_remove_file(
+        VFSContext *ctx,
+        PgVFS *pg,
+        int64_t resource_id,
+        Oid oid)
+{
+    if(oid > 0) {
+        if(lo_unlink(pg->connection, oid) != 1) {
+            return 1; // error
+        }
+    }
+    
+    char resid_str[32];
+    snprintf(resid_str, 32, "%" PRId64, resource_id);
+    
+    const char* params[1] = { resid_str };
+    PGresult *result = PQexecParams(
+            pg->connection,
+            sql_delete_res,
+            1,     // number of parameters
+            NULL,
+            params, // parameter value
+            NULL,
+            NULL,
+            0);    // 0: result in text format
+    
+    int ret = PQresultStatus(result) == PGRES_COMMAND_OK ? 0 : 1;
+    PQclear(result);
+    return ret;
+}
+
 int pg_update_resource(PgVFS *pg, int64_t resource_id, int64_t contentlength) {
     char resid_str[32];
     char ctlen_str[32];
@@ -622,7 +657,26 @@
 }
 
 int pg_vfs_unlink(VFSContext *ctx, const char *path) {
-    return 1;
+    VFS *vfs = ctx->vfs;
+    PgVFS *pg = vfs->instance;
+    
+    const char *resname;
+    int64_t resource_id, parent_id;
+    resource_id = -1;
+    parent_id = -1;
+    WSBool iscollection;
+    Oid oid = 0;
+    if(pg_resolve_path(ctx, path, &parent_id, &resource_id, &oid, &resname, &iscollection, NULL)) {
+        ctx->vfs_errno = ENOENT;
+        return 1;
+    }
+    
+    if(iscollection) {
+        ctx->vfs_errno = EISDIR;
+        return 1;
+    }
+    
+    return pg_remove_file(ctx, pg, resource_id, oid);
 }
 
 int pg_vfs_rmdir(VFSContext *Ctx, const char *path) {
--- a/src/server/plugins/postgresql/vfs.h	Sun Apr 17 12:04:41 2022 +0200
+++ b/src/server/plugins/postgresql/vfs.h	Mon Apr 18 10:53:13 2022 +0200
@@ -102,6 +102,12 @@
         struct stat *s,
         WSBool collection);
 
+int pg_remove_file(
+        VFSContext *ctx,
+        PgVFS *pg,
+        int64_t resource_id,
+        Oid oid);
+
 int pg_update_resource(PgVFS *pg, int64_t resource_id, int64_t contentlength);
     
 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags);

mercurial