src/server/plugins/postgresql/vfs.c

branch
webdav
changeset 374
77506ec632a4
parent 372
1d2538a1ba8f
child 379
4e2cb3adc0f2
equal deleted inserted replaced
373:f78a585e1a2f 374:77506ec632a4
81 contentlength,\n\ 81 contentlength,\n\
82 etag,\n\ 82 etag,\n\
83 regexp_split_to_array($1, '/') as pathelm,\n\ 83 regexp_split_to_array($1, '/') as pathelm,\n\
84 1 as pathdepth\n\ 84 1 as pathdepth\n\
85 from Resource\n\ 85 from Resource\n\
86 where parent_id is null\n\ 86 where resource_id = $2\n\
87 union\n\ 87 union\n\
88 select\n\ 88 select\n\
89 r.resource_id,\n\ 89 r.resource_id,\n\
90 r.parent_id,\n\ 90 r.parent_id,\n\
91 p.fullpath || '/' || r.nodename,\n\ 91 p.fullpath || '/' || r.nodename,\n\
104 select resource_id, parent_id, fullpath, resoid, iscollection, lastmodified, creationdate, contentlength, etag from resolvepath\n\ 104 select resource_id, parent_id, fullpath, resoid, iscollection, lastmodified, creationdate, contentlength, etag from resolvepath\n\
105 where fullpath = $1 ;"; 105 where fullpath = $1 ;";
106 106
107 // Same as sql_resolve_path, but it returns the root collection 107 // Same as sql_resolve_path, but it returns the root collection
108 // params: $1: path string (should be '/') 108 // params: $1: path string (should be '/')
109 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;"; 109 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;";
110 110
111 // Get all children of a specific collection 111 // Get all children of a specific collection
112 // params: $1: parent resource_id 112 // params: $1: parent resource_id
113 static const char *sql_get_children = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength, etag from Resource where parent_id = $1;"; 113 static const char *sql_get_children = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength, etag from Resource where parent_id = $1;";
114 114
167 log_ereport(LOG_MISCONFIG, "postgresql vfs: resource pool %s not found", resource_pool); 167 log_ereport(LOG_MISCONFIG, "postgresql vfs: resource pool %s not found", resource_pool);
168 return NULL; 168 return NULL;
169 } 169 }
170 // resdata will be freed automatically when the request is finished 170 // resdata will be freed automatically when the request is finished
171 171
172 return pg_vfs_create_from_resourcedata(sn, rq, resdata); 172 return pg_vfs_create_from_resourcedata(sn, rq, repo, resdata);
173 } 173 }
174 174
175 VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, ResourceData *resdata) { 175 VFS* pg_vfs_create_from_resourcedata(Session *sn, Request *rq, PgRepository *repo, ResourceData *resdata) {
176 // Create a new VFS object and a separate instance object 176 // Create a new VFS object and a separate instance object
177 // VFS contains fptrs that can be copied from pg_vfs_class 177 // VFS contains fptrs that can be copied from pg_vfs_class
178 // instance contains request specific data (PGconn) 178 // instance contains request specific data (PGconn)
179 VFS *vfs = pool_malloc(sn->pool, sizeof(VFS)); 179 VFS *vfs = pool_malloc(sn->pool, sizeof(VFS));
180 if(!vfs) { 180 if(!vfs) {
186 pool_free(sn->pool, vfs); 186 pool_free(sn->pool, vfs);
187 return NULL; 187 return NULL;
188 } 188 }
189 vfs_priv->connection = resdata->data; 189 vfs_priv->connection = resdata->data;
190 vfs_priv->pg_resource = resdata; 190 vfs_priv->pg_resource = resdata;
191 vfs_priv->root_resource_id = repo->root_resource_id;
192 snprintf(vfs_priv->root_resource_id_str, 32, "%" PRId64, repo->root_resource_id);
191 193
192 memcpy(vfs, &pg_vfs_class, sizeof(VFS)); 194 memcpy(vfs, &pg_vfs_class, sizeof(VFS));
193 vfs->flags = 0; 195 vfs->flags = 0;
194 vfs->instance = vfs_priv; 196 vfs->instance = vfs_priv;
195 197
198 200
199 201
200 int pg_resolve_path( 202 int pg_resolve_path(
201 PGconn *connection, 203 PGconn *connection,
202 const char *path, 204 const char *path,
205 const char *root_id,
203 int64_t *parent_id, 206 int64_t *parent_id,
204 int64_t *resource_id, 207 int64_t *resource_id,
205 Oid *oid, 208 Oid *oid,
206 const char **resource_name, 209 const char **resource_name,
207 WSBool *iscollection, 210 WSBool *iscollection,
226 } 229 }
227 230
228 // get last node of path 231 // get last node of path
229 *resource_name = util_resource_name(path); 232 *resource_name = util_resource_name(path);
230 233
231 const char *sql = pathlen == 1 ? sql_get_root : sql_resolve_path; 234 const char *sql = pathlen == 1 ? sql_get_root : sql_resolve_path;
235 const char* params[2] = { path, root_id };
232 PGresult *result = PQexecParams( 236 PGresult *result = PQexecParams(
233 connection, 237 connection,
234 sql, 238 sql,
235 1, // number of parameters 239 2, // number of parameters
236 NULL, 240 NULL,
237 &path, // parameter value 241 params, // parameter value
238 NULL, 242 NULL,
239 NULL, 243 NULL,
240 0); // 0: result in text format 244 0); // 0: result in text format
241 245
242 if(pathf) { 246 if(pathf) {
461 resource_id = -1; 465 resource_id = -1;
462 parent_id = -1; 466 parent_id = -1;
463 WSBool iscollection; 467 WSBool iscollection;
464 Oid unused_oid = 0; 468 Oid unused_oid = 0;
465 469
466 int err = pg_resolve_path(pg->connection, parent_path, &parent_id, &resource_id, &unused_oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno); 470 int err = pg_resolve_path(
471 pg->connection,
472 parent_path,
473 pg->root_resource_id_str,
474 &parent_id,
475 &resource_id,
476 &unused_oid,
477 &resname,
478 &iscollection,
479 NULL,
480 NULL,
481 &ctx->vfs_errno);
467 FREE(parent_path); 482 FREE(parent_path);
468 if(err) { 483 if(err) {
469 ctx->vfs_errno = ENOENT; 484 ctx->vfs_errno = ENOENT;
470 if(pathf) free(pathf); 485 if(pathf) free(pathf);
471 return 1; 486 return 1;
587 parent_id = -1; 602 parent_id = -1;
588 WSBool iscollection; 603 WSBool iscollection;
589 struct stat s; 604 struct stat s;
590 char etag[PG_ETAG_MAXLEN]; 605 char etag[PG_ETAG_MAXLEN];
591 Oid oid = 0; 606 Oid oid = 0;
592 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, etag, &ctx->vfs_errno)) { 607 if(pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, etag, &ctx->vfs_errno)) {
593 if((oflags & O_CREAT) == O_CREAT) { 608 if((oflags & O_CREAT) == O_CREAT) {
594 if(pg_create_file(ctx, pg, path, &resource_id, &parent_id, &oid, &resname, &s, FALSE)) { 609 if(pg_create_file(ctx, pg, path, &resource_id, &parent_id, &oid, &resname, &s, FALSE)) {
595 return NULL; 610 return NULL;
596 } 611 }
597 iscollection = 0; 612 iscollection = 0;
662 PgVFS *pg = vfs->instance; 677 PgVFS *pg = vfs->instance;
663 678
664 int64_t parent_id, resource_id; 679 int64_t parent_id, resource_id;
665 const char *resname; 680 const char *resname;
666 WSBool iscollection; 681 WSBool iscollection;
667 return pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, buf, NULL, &ctx->vfs_errno); 682 return pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, NULL, &resname, &iscollection, buf, NULL, &ctx->vfs_errno);
668 } 683 }
669 684
670 int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) { 685 int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) {
671 PgFile *pgfile = fd->data; 686 PgFile *pgfile = fd->data;
672 memcpy(buf, &pgfile->s, sizeof(struct stat)); 687 memcpy(buf, &pgfile->s, sizeof(struct stat));
720 resource_id = -1; 735 resource_id = -1;
721 parent_id = -1; 736 parent_id = -1;
722 WSBool iscollection; 737 WSBool iscollection;
723 struct stat s; 738 struct stat s;
724 Oid oid = 0; 739 Oid oid = 0;
725 if(!pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, NULL, &ctx->vfs_errno)) { 740 if(!pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, NULL, &ctx->vfs_errno)) {
726 ctx->vfs_errno = EEXIST; 741 ctx->vfs_errno = EEXIST;
727 return 1; 742 return 1;
728 } 743 }
729 744
730 if(pg_create_file(ctx, pg, path, NULL, NULL, NULL, NULL, NULL, TRUE)) { 745 if(pg_create_file(ctx, pg, path, NULL, NULL, NULL, NULL, NULL, TRUE)) {
742 int64_t resource_id, parent_id; 757 int64_t resource_id, parent_id;
743 resource_id = -1; 758 resource_id = -1;
744 parent_id = -1; 759 parent_id = -1;
745 WSBool iscollection; 760 WSBool iscollection;
746 Oid oid = 0; 761 Oid oid = 0;
747 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { 762 if(pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, &oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) {
748 return 1; 763 return 1;
749 } 764 }
750 765
751 if(iscollection) { 766 if(iscollection) {
752 ctx->vfs_errno = EISDIR; 767 ctx->vfs_errno = EISDIR;
763 const char *resname; 778 const char *resname;
764 int64_t resource_id, parent_id; 779 int64_t resource_id, parent_id;
765 resource_id = -1; 780 resource_id = -1;
766 parent_id = -1; 781 parent_id = -1;
767 WSBool iscollection; 782 WSBool iscollection;
768 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { 783 if(pg_resolve_path(pg->connection, path, pg->root_resource_id_str, &parent_id, &resource_id, NULL, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) {
769 return 1; 784 return 1;
770 } 785 }
771 786
772 if(!iscollection) { 787 if(!iscollection) {
773 ctx->vfs_errno = ENOTDIR; 788 ctx->vfs_errno = ENOTDIR;

mercurial