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 |
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; |