diff -r cfb588e27198 -r 25e5b771677d src/server/plugins/postgresql/vfs.c --- 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); }