# HG changeset patch # User Olaf Wintermann # Date 1650187153 -7200 # Node ID efc10acf539f37770128eaea3696b2121c0097f9 # Parent 285d483db2fbb657e867cfd871126177d76c14e3 implement pg vfs mkdir diff -r 285d483db2fb -r efc10acf539f src/server/plugins/postgresql/pgtest.c --- a/src/server/plugins/postgresql/pgtest.c Sat Apr 16 21:05:29 2022 +0200 +++ b/src/server/plugins/postgresql/pgtest.c Sun Apr 17 11:19:13 2022 +0200 @@ -161,3 +161,19 @@ } +UCX_TEST(test_pg_vfs_stat) { + 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); + SYS_FILE file; + SYS_FILE file2; + + UCX_TEST_BEGIN; + + UCX_TEST_END; +} + +UCX_TEST(test_pg_vfs_mkdir) { + +} diff -r 285d483db2fb -r efc10acf539f src/server/plugins/postgresql/pgtest.h --- a/src/server/plugins/postgresql/pgtest.h Sat Apr 16 21:05:29 2022 +0200 +++ b/src/server/plugins/postgresql/pgtest.h Sun Apr 17 11:19:13 2022 +0200 @@ -24,7 +24,8 @@ UCX_TEST(test_pg_vfs_open); UCX_TEST(test_pg_vfs_io); - +UCX_TEST(test_pg_vfs_stat); +UCX_TEST(test_pg_vfs_mkdir); #ifdef __cplusplus } diff -r 285d483db2fb -r efc10acf539f src/server/plugins/postgresql/vfs.c --- a/src/server/plugins/postgresql/vfs.c Sat Apr 16 21:05:29 2022 +0200 +++ b/src/server/plugins/postgresql/vfs.c Sun Apr 17 11:19:13 2022 +0200 @@ -120,6 +120,14 @@ ($1, $2, false, now(), now(), 0, lo_creat(-1))\n\ returning resource_id, resoid, lastmodified, creationdate;"; +// Create collection +// params: $1: parent_id +// $2: node name +static const char *sql_create_collection = + "insert into Resource (parent_id, nodename, iscollection, lastmodified, creationdate, contentlength) values\n\ + ($1, $2, true, now(), now(), 0)\n\ + returning resource_id, lastmodified, creationdate;"; + VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb) { // resourcepool is required char *resource_pool = pblock_findval("resourcepool", pb); @@ -282,6 +290,116 @@ } } +static int pg_create_res( + PgVFS *pg, + const char *resparentid_str, + const char *nodename, + int64_t *new_resource_id, + Oid *oid, + const char **resource_name, + struct stat *s) +{ + const char* params[2] = { resparentid_str, nodename }; + PGresult *result = PQexecParams( + pg->connection, + sql_create_resource, + 2, // number of parameters + NULL, + params, // parameter value + NULL, + NULL, + 0); // 0: result in text format + + if(!result) return 1; + + int ret = 1; + if(PQntuples(result) == 1) { + // sql insert succesful + ret = 0; + + char *id_str = PQgetvalue(result, 0, 0); + char *oid_str = PQgetvalue(result, 0, 1); + char *lastmodified = PQgetvalue(result, 0, 2); + char *creationdate = PQgetvalue(result, 0, 3); + + if(new_resource_id) { + if(!id_str || !util_strtoint(id_str, new_resource_id)) { + ret = 1; // shouldn't happen + log_ereport(LOG_FAILURE, "Postgresql VFS: sql_create_resource: Could not convert resource_id to int"); + } + } + if(oid) { + int64_t i; + if(!oid_str || !util_strtoint(oid_str, &i)) { + ret = 1; // shouldn't happen + log_ereport(LOG_FAILURE, "Postgresql VFS: sql_create_resource: Could not convert oid to int"); + } else { + *oid = i; + } + } + if(resource_name) { + *resource_name = nodename; + } + if(s) { + pg_set_stat(s, 0, lastmodified, creationdate, NULL); + } + } + + PQclear(result); + + return ret; +} + + +static int pg_create_col( + PgVFS *pg, + const char *resparentid_str, + const char *nodename, + int64_t *new_resource_id, + const char **resource_name, + struct stat *s) +{ + const char* params[2] = { resparentid_str, nodename }; + PGresult *result = PQexecParams( + pg->connection, + sql_create_collection, + 2, // number of parameters + NULL, + params, // parameter value + NULL, + NULL, + 0); // 0: result in text format + + if(!result) return 1; + + int ret = 1; + if(PQntuples(result) == 1) { + // sql insert succesful + ret = 0; + + char *id_str = PQgetvalue(result, 0, 0); + char *lastmodified = PQgetvalue(result, 0, 1); + char *creationdate = PQgetvalue(result, 0, 2); + + if(new_resource_id) { + if(!id_str || !util_strtoint(id_str, new_resource_id)) { + ret = 1; // shouldn't happen + log_ereport(LOG_FAILURE, "Postgresql VFS: sql_create_collection: Could not convert resource_id to int"); + } + } + if(resource_name) { + *resource_name = nodename; + } + if(s) { + pg_set_stat(s, 0, lastmodified, creationdate, NULL); + } + } + + PQclear(result); + + return ret; +} + int pg_create_file( VFSContext *ctx, PgVFS *pg, @@ -290,7 +408,8 @@ int64_t *res_parent_id, Oid *oid, const char **resource_name, - struct stat *s) + struct stat *s, + WSBool collection) { char *parent_path = util_parent_path(path); if(!parent_path) return 1; @@ -321,57 +440,17 @@ char resid_str[32]; snprintf(resid_str, 32, "%" PRId64, resource_id); // convert parent resource_id to string - const char* params[2] = { resid_str, nodename }; - PGresult *result = PQexecParams( - pg->connection, - sql_create_resource, - 2, // number of parameters - NULL, - params, // parameter value - NULL, - NULL, - 0); // 0: result in text format - - if(!result) return 1; - - int ret = 1; - if(PQntuples(result) == 1) { - // sql insert succesful - ret = 0; - - char *id_str = PQgetvalue(result, 0, 0); - char *oid_str = PQgetvalue(result, 0, 1); - char *lastmodified = PQgetvalue(result, 0, 2); - char *creationdate = PQgetvalue(result, 0, 3); - - if(new_resource_id) { - if(!id_str || !util_strtoint(id_str, new_resource_id)) { - ret = 1; // shouldn't happen - log_ereport(LOG_FAILURE, "Postgresql VFS: sql_create_resource: Could not convert resource_id to int"); - } - } - if(res_parent_id) { - // resource_id is still the id of the parent from previous pg_resolve_path call - *res_parent_id = resource_id; - } - if(oid) { - int64_t i; - if(!oid_str || !util_strtoint(oid_str, &i)) { - ret = 1; // shouldn't happen - log_ereport(LOG_FAILURE, "Postgresql VFS: sql_create_resource: Could not convert oid to int"); - } else { - *oid = i; - } - } - if(resource_name) { - *resource_name = nodename; - } - if(s) { - pg_set_stat(s, 0, lastmodified, creationdate, NULL); - } + int ret; + if(collection) { + ret = pg_create_col(pg, resid_str, nodename, new_resource_id, resource_name, s); + } else { + ret = pg_create_res(pg, resid_str, nodename, new_resource_id, oid, resource_name, s); } - PQclear(result); + if(res_parent_id) { + // resource_id is still the id of the parent from previous pg_resolve_path call + *res_parent_id = resource_id; + } return ret; } @@ -391,7 +470,7 @@ Oid oid = 0; if(pg_resolve_path(ctx, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s)) { if((oflags & O_CREAT) == O_CREAT) { - if(pg_create_file(ctx, pg, path, &resource_id, &parent_id, &oid, &resname, &s)) { + if(pg_create_file(ctx, pg, path, &resource_id, &parent_id, &oid, &resname, &s, FALSE)) { return NULL; } iscollection = 0; @@ -492,7 +571,26 @@ } int pg_vfs_mkdir(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; + struct stat s; + Oid oid = 0; + if(!pg_resolve_path(ctx, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s)) { + ctx->vfs_errno = EEXIST; + return 1; + } + + if(pg_create_file(ctx, pg, path, NULL, NULL, NULL, NULL, NULL, TRUE)) { + return 1; + } + + return 0; } int pg_vfs_unlink(VFSContext *ctx, const char *path) { diff -r 285d483db2fb -r efc10acf539f src/server/plugins/postgresql/vfs.h --- a/src/server/plugins/postgresql/vfs.h Sat Apr 16 21:05:29 2022 +0200 +++ b/src/server/plugins/postgresql/vfs.h Sun Apr 17 11:19:13 2022 +0200 @@ -98,7 +98,8 @@ int64_t *res_parent_id, Oid *oid, const char **resource_name, - struct stat *s); + struct stat *s, + WSBool collection); SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags); int pg_vfs_stat(VFSContext *ctx, const char *path, struct stat *buf);