src/server/plugins/postgresql/vfs.c

branch
webdav
changeset 283
25e5b771677d
parent 282
cfb588e27198
child 284
eab579b8c80d
--- a/src/server/plugins/postgresql/vfs.c	Tue Feb 01 20:07:42 2022 +0100
+++ b/src/server/plugins/postgresql/vfs.c	Thu Feb 03 17:26:08 2022 +0100
@@ -72,6 +72,7 @@
             resource_id,\n\
             parent_id,\n\
             '' as fullpath,\n\
+            resoid,\n\
             iscollection,\n\
             lastmodified,\n\
             creationdate,\n\
@@ -85,6 +86,7 @@
             r.resource_id,\n\
             r.parent_id,\n\
             p.fullpath || '/' || r.nodename,\n\
+            r.resoid,\n\
             r.iscollection,\n\
             r.lastmodified,\n\
             r.creationdate,\n\
@@ -95,12 +97,12 @@
         inner join resolvepath p on r.parent_id = p.resource_id\n\
         where p.pathelm[p.pathdepth+1] = r.nodename\n\
     )\n\
-    select resource_id, parent_id, fullpath, iscollection from resolvepath\n\
+    select resource_id, parent_id, fullpath, resoid, iscollection, lastmodified, creationdate, contentlength from resolvepath\n\
     where fullpath = $1 ;";
 
 // 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, true as iscollection, lastmodified, creationdate, contentlength 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 from Resource where parent_id is null;";
 
 // Get all children of a specific collection
 // params: $1: parent resource_id
@@ -155,6 +157,7 @@
         const char *path,
         int64_t *parent_id,
         int64_t *resource_id,
+        Oid *oid,
         const char **resource_name,
         WSBool *iscollection,
         struct stat *s)
@@ -191,7 +194,7 @@
             NULL,
             NULL,
             0);    // 0: result in text format
-    
+      
     if(pathf) {
         free(pathf);
     }
@@ -204,10 +207,10 @@
     if(nrows == 1) {
         char *resource_id_str = PQgetvalue(result, 0, 0);
         char *parent_id_str = PQgetvalue(result, 0, 1);
-        char *iscol = PQgetvalue(result, 0, 3);
-        char *lastmodified = PQgetvalue(result, 0, 4);
-        char *creationdate = PQgetvalue(result, 0, 5);
-        char *contentlength = PQgetvalue(result, 0, 6);
+        char *iscol = PQgetvalue(result, 0, 4);
+        char *lastmodified = PQgetvalue(result, 0, 5);
+        char *creationdate = PQgetvalue(result, 0, 6);
+        char *contentlength = PQgetvalue(result, 0, 7);
         if(resource_id_str && parent_id_str) {
             if(util_strtoint(resource_id_str, resource_id)) {
                 ret = 0; // success
@@ -216,6 +219,14 @@
             util_strtoint(parent_id_str, parent_id);
         }
         
+        if(oid) {
+            char *resoid = PQgetvalue(result, 0, 3);
+            int64_t roid;
+            if(resoid && util_strtoint(resoid, &roid)) {
+                *oid = roid;
+            }
+        }
+        
         if(iscollection && iscol) {
             *iscollection = iscol[0] == 't' ? TRUE : FALSE;
         }
@@ -248,6 +259,9 @@
         }
     }
     // TODO: lastmodified, creationdate
+    // set some test values != 0
+    s->st_mtime = time(NULL);
+    
     if(contentlength) {
         int64_t len;
         if(util_strtoint(contentlength, &len)) {
@@ -259,13 +273,17 @@
 /* -------------------------- VFS functions -------------------------- */
 
 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags) {
+    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;
     struct stat s;
-    if(pg_resolve_path(ctx, path, &parent_id, &resource_id, &resname, &iscollection, &s)) {
+    Oid oid = 0;
+    if(pg_resolve_path(ctx, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s)) {
         return NULL;
     }
     
@@ -279,9 +297,21 @@
         return NULL;
     }
     
+    int fd = -1;
+    if(!iscollection) {
+        if (PQstatus(pg->connection) != CONNECTION_OK) {
+            fd = -2;
+        }
+        
+        int lo_mode = INV_READ; // TODO: evaluate oflags
+        fd = lo_open(pg->connection, oid, lo_mode);
+    }
+    
     pgfile->iscollection = iscollection;
     pgfile->resource_id = resource_id;
     pgfile->parent_id = parent_id;
+    pgfile->oid = oid;
+    pgfile->fd = fd;
     pgfile->s = s;
     
     file->ctx = ctx;
@@ -296,7 +326,7 @@
     int64_t parent_id, resource_id;
     const char *resname;
     WSBool iscollection;
-    return pg_resolve_path(ctx, path, &parent_id, &resource_id, &resname, &iscollection, buf);
+    return pg_resolve_path(ctx, path, &parent_id, &resource_id, NULL, &resname, &iscollection, buf);
 }
 
 int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) {
@@ -359,22 +389,32 @@
 /* -------------------------- VFS_IO functions -------------------------- */
 
 ssize_t pg_vfs_io_read(SYS_FILE fd, void *buf, size_t nbyte) {
-    return 0;
+    PgVFS *pgvfs = fd->ctx->vfs->instance;
+    PgFile *pg = fd->data;
+    return lo_read(pgvfs->connection, pg->fd, buf, nbyte);
 }
 
 ssize_t pg_vfs_io_write(SYS_FILE fd, const void *buf, size_t nbyte) {
+    PgVFS *pgvfs = fd->ctx->vfs->instance;
+    
     return 0;
 }
 
 ssize_t pg_vfs_io_pread(SYS_FILE fd, void *buf, size_t nbyte, off_t offset) {
+    PgVFS *pgvfs = fd->ctx->vfs->instance;
+    
     return 0;
 }
 
 ssize_t pg_vfs_io_pwrite(SYS_FILE fd, const void *buf, size_t nbyte, off_t offset) {
+    PgVFS *pgvfs = fd->ctx->vfs->instance;
+    
     return 0;
 }
 
 off_t pg_vfs_io_seek(SYS_FILE fd, off_t offset, int whence) {
+    PgVFS *pgvfs = fd->ctx->vfs->instance;
+    
     return 0;
 }
 
@@ -382,6 +422,11 @@
     pool_handle_t *pool = fd->ctx->pool;
     PgFile *pg = fd->data;
     
+    if(pg->fd >= 0) {
+        PgVFS *pgvfs = fd->ctx->vfs->instance;
+        lo_close(pgvfs->connection, pg->fd);
+    }
+    
     pool_free(pool, pg);
     pool_free(pool, fd);
 }

mercurial