90 r.resoid,\n\ |
91 r.resoid,\n\ |
91 r.iscollection,\n\ |
92 r.iscollection,\n\ |
92 r.lastmodified,\n\ |
93 r.lastmodified,\n\ |
93 r.creationdate,\n\ |
94 r.creationdate,\n\ |
94 r.contentlength,\n\ |
95 r.contentlength,\n\ |
|
96 r.etag,\n\ |
95 p.pathelm,\n\ |
97 p.pathelm,\n\ |
96 p.pathdepth + 1\n\ |
98 p.pathdepth + 1\n\ |
97 from Resource r\n\ |
99 from Resource r\n\ |
98 inner join resolvepath p on r.parent_id = p.resource_id\n\ |
100 inner join resolvepath p on r.parent_id = p.resource_id\n\ |
99 where p.pathelm[p.pathdepth+1] = r.nodename\n\ |
101 where p.pathelm[p.pathdepth+1] = r.nodename\n\ |
100 )\n\ |
102 )\n\ |
101 select resource_id, parent_id, fullpath, resoid, iscollection, lastmodified, creationdate, contentlength from resolvepath\n\ |
103 select resource_id, parent_id, fullpath, resoid, iscollection, lastmodified, creationdate, contentlength, etag from resolvepath\n\ |
102 where fullpath = $1 ;"; |
104 where fullpath = $1 ;"; |
103 |
105 |
104 // Same as sql_resolve_path, but it returns the root collection |
106 // Same as sql_resolve_path, but it returns the root collection |
105 // params: $1: path string (should be '/') |
107 // params: $1: path string (should be '/') |
106 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;"; |
108 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;"; |
107 |
109 |
108 // Get all children of a specific collection |
110 // Get all children of a specific collection |
109 // params: $1: parent resource_id |
111 // params: $1: parent resource_id |
110 static const char *sql_get_children = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength from Resource where parent_id = $1;"; |
112 static const char *sql_get_children = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength, etag from Resource where parent_id = $1;"; |
111 |
113 |
112 // Get resource |
114 // Get resource |
113 // params: $1: resource_id |
115 // params: $1: resource_id |
114 static const char *sql_get_resource = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength from Resource where resource_id = $1;"; |
116 static const char *sql_get_resource = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength, etag from Resource where resource_id = $1;"; |
115 |
117 |
116 // Create resource |
118 // Create resource |
117 // params: $1: parent_id |
119 // params: $1: parent_id |
118 // $2: node name |
120 // $2: node name |
119 static const char *sql_create_resource = |
121 static const char *sql_create_resource = |
189 int64_t *resource_id, |
191 int64_t *resource_id, |
190 Oid *oid, |
192 Oid *oid, |
191 const char **resource_name, |
193 const char **resource_name, |
192 WSBool *iscollection, |
194 WSBool *iscollection, |
193 struct stat *s, |
195 struct stat *s, |
|
196 char *etag, |
194 int *res_errno) |
197 int *res_errno) |
195 { |
198 { |
196 // basic path validation |
199 // basic path validation |
197 if(!path) return 1; |
200 if(!path) return 1; |
198 size_t pathlen = strlen(path); |
201 size_t pathlen = strlen(path); |
237 char *parent_id_str = PQgetvalue(result, 0, 1); |
240 char *parent_id_str = PQgetvalue(result, 0, 1); |
238 char *iscol = PQgetvalue(result, 0, 4); |
241 char *iscol = PQgetvalue(result, 0, 4); |
239 char *lastmodified = PQgetvalue(result, 0, 5); |
242 char *lastmodified = PQgetvalue(result, 0, 5); |
240 char *creationdate = PQgetvalue(result, 0, 6); |
243 char *creationdate = PQgetvalue(result, 0, 6); |
241 char *contentlength = PQgetvalue(result, 0, 7); |
244 char *contentlength = PQgetvalue(result, 0, 7); |
|
245 char *res_etag = PQgetvalue(result, 0, 8); |
242 if(resource_id_str && parent_id_str) { |
246 if(resource_id_str && parent_id_str) { |
243 if(util_strtoint(resource_id_str, resource_id)) { |
247 if(util_strtoint(resource_id_str, resource_id)) { |
244 ret = 0; // success |
248 ret = 0; // success |
245 } |
249 } |
246 // optionally get parent_id |
250 // optionally get parent_id |
259 *iscollection = iscol[0] == 't' ? TRUE : FALSE; |
263 *iscollection = iscol[0] == 't' ? TRUE : FALSE; |
260 } |
264 } |
261 |
265 |
262 if(s) { |
266 if(s) { |
263 pg_set_stat(s, iscol, lastmodified, creationdate, contentlength); |
267 pg_set_stat(s, iscol, lastmodified, creationdate, contentlength); |
|
268 } |
|
269 |
|
270 if(etag) { |
|
271 size_t etag_len = strlen(res_etag); |
|
272 if(etag_len < PG_ETAG_MAXLEN) |
|
273 memcpy(etag, res_etag, etag_len+1); |
264 } |
274 } |
265 } else if(res_errno) { |
275 } else if(res_errno) { |
266 *res_errno = ENOENT; |
276 *res_errno = ENOENT; |
267 } |
277 } |
268 |
278 |
429 resource_id = -1; |
439 resource_id = -1; |
430 parent_id = -1; |
440 parent_id = -1; |
431 WSBool iscollection; |
441 WSBool iscollection; |
432 Oid unused_oid = 0; |
442 Oid unused_oid = 0; |
433 |
443 |
434 int err = pg_resolve_path(pg->connection, parent_path, &parent_id, &resource_id, &unused_oid, &resname, &iscollection, NULL, &ctx->vfs_errno); |
444 int err = pg_resolve_path(pg->connection, parent_path, &parent_id, &resource_id, &unused_oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno); |
435 FREE(parent_path); |
445 FREE(parent_path); |
436 if(err) { |
446 if(err) { |
437 ctx->vfs_errno = ENOENT; |
447 ctx->vfs_errno = ENOENT; |
438 return 1; |
448 return 1; |
439 } |
449 } |
549 int64_t resource_id, parent_id; |
559 int64_t resource_id, parent_id; |
550 resource_id = -1; |
560 resource_id = -1; |
551 parent_id = -1; |
561 parent_id = -1; |
552 WSBool iscollection; |
562 WSBool iscollection; |
553 struct stat s; |
563 struct stat s; |
|
564 char etag[PG_ETAG_MAXLEN]; |
554 Oid oid = 0; |
565 Oid oid = 0; |
555 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, &ctx->vfs_errno)) { |
566 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, etag, &ctx->vfs_errno)) { |
556 if((oflags & O_CREAT) == O_CREAT) { |
567 if((oflags & O_CREAT) == O_CREAT) { |
557 if(pg_create_file(ctx, pg, path, &resource_id, &parent_id, &oid, &resname, &s, FALSE)) { |
568 if(pg_create_file(ctx, pg, path, &resource_id, &parent_id, &oid, &resname, &s, FALSE)) { |
558 return NULL; |
569 return NULL; |
559 } |
570 } |
560 iscollection = 0; |
571 iscollection = 0; |
624 PgVFS *pg = vfs->instance; |
636 PgVFS *pg = vfs->instance; |
625 |
637 |
626 int64_t parent_id, resource_id; |
638 int64_t parent_id, resource_id; |
627 const char *resname; |
639 const char *resname; |
628 WSBool iscollection; |
640 WSBool iscollection; |
629 return pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, buf, &ctx->vfs_errno); |
641 return pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, buf, NULL, &ctx->vfs_errno); |
630 } |
642 } |
631 |
643 |
632 int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) { |
644 int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) { |
633 PgFile *pgfile = fd->data; |
645 PgFile *pgfile = fd->data; |
634 memcpy(buf, &pgfile->s, sizeof(struct stat)); |
646 memcpy(buf, &pgfile->s, sizeof(struct stat)); |
682 resource_id = -1; |
694 resource_id = -1; |
683 parent_id = -1; |
695 parent_id = -1; |
684 WSBool iscollection; |
696 WSBool iscollection; |
685 struct stat s; |
697 struct stat s; |
686 Oid oid = 0; |
698 Oid oid = 0; |
687 if(!pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, &ctx->vfs_errno)) { |
699 if(!pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s, NULL, &ctx->vfs_errno)) { |
688 ctx->vfs_errno = EEXIST; |
700 ctx->vfs_errno = EEXIST; |
689 return 1; |
701 return 1; |
690 } |
702 } |
691 |
703 |
692 if(pg_create_file(ctx, pg, path, NULL, NULL, NULL, NULL, NULL, TRUE)) { |
704 if(pg_create_file(ctx, pg, path, NULL, NULL, NULL, NULL, NULL, TRUE)) { |
704 int64_t resource_id, parent_id; |
716 int64_t resource_id, parent_id; |
705 resource_id = -1; |
717 resource_id = -1; |
706 parent_id = -1; |
718 parent_id = -1; |
707 WSBool iscollection; |
719 WSBool iscollection; |
708 Oid oid = 0; |
720 Oid oid = 0; |
709 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, NULL, &ctx->vfs_errno)) { |
721 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, &oid, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { |
710 return 1; |
722 return 1; |
711 } |
723 } |
712 |
724 |
713 if(iscollection) { |
725 if(iscollection) { |
714 ctx->vfs_errno = EISDIR; |
726 ctx->vfs_errno = EISDIR; |
725 const char *resname; |
737 const char *resname; |
726 int64_t resource_id, parent_id; |
738 int64_t resource_id, parent_id; |
727 resource_id = -1; |
739 resource_id = -1; |
728 parent_id = -1; |
740 parent_id = -1; |
729 WSBool iscollection; |
741 WSBool iscollection; |
730 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, NULL, &ctx->vfs_errno)) { |
742 if(pg_resolve_path(pg->connection, path, &parent_id, &resource_id, NULL, &resname, &iscollection, NULL, NULL, &ctx->vfs_errno)) { |
731 return 1; |
743 return 1; |
732 } |
744 } |
733 |
745 |
734 if(!iscollection) { |
746 if(!iscollection) { |
735 ctx->vfs_errno = ENOTDIR; |
747 ctx->vfs_errno = ENOTDIR; |