src/server/plugins/postgresql/vfs.c

branch
webdav
changeset 346
784b24381bed
parent 345
5832e10fc59a
child 347
b6d71e504294
equal deleted inserted replaced
345:5832e10fc59a 346:784b24381bed
76 resoid,\n\ 76 resoid,\n\
77 iscollection,\n\ 77 iscollection,\n\
78 lastmodified,\n\ 78 lastmodified,\n\
79 creationdate,\n\ 79 creationdate,\n\
80 contentlength,\n\ 80 contentlength,\n\
81 etag,\n\
81 regexp_split_to_array($1, '/') as pathelm,\n\ 82 regexp_split_to_array($1, '/') as pathelm,\n\
82 1 as pathdepth\n\ 83 1 as pathdepth\n\
83 from Resource\n\ 84 from Resource\n\
84 where parent_id is null\n\ 85 where parent_id is null\n\
85 union\n\ 86 union\n\
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;
608 pgfile->parent_id = parent_id; 619 pgfile->parent_id = parent_id;
609 pgfile->oid = oid; 620 pgfile->oid = oid;
610 pgfile->fd = fd; 621 pgfile->fd = fd;
611 pgfile->oflags = oflags; 622 pgfile->oflags = oflags;
612 pgfile->s = s; 623 pgfile->s = s;
624 memcpy(pgfile->etag, etag, PG_ETAG_MAXLEN);
613 625
614 file->ctx = ctx; 626 file->ctx = ctx;
615 file->io = iscollection ? &pg_vfs_io_class : &pg_vfs_io_class; 627 file->io = iscollection ? &pg_vfs_io_class : &pg_vfs_io_class;
616 file->fd = -1; 628 file->fd = -1;
617 file->data = pgfile; 629 file->data = pgfile;
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;
805 pool_free(pool, pg); 817 pool_free(pool, pg);
806 pool_free(pool, fd); 818 pool_free(pool, fd);
807 } 819 }
808 820
809 const char *pg_vfs_io_getetag(SYS_FILE fd) { 821 const char *pg_vfs_io_getetag(SYS_FILE fd) {
810 return NULL; 822 PgFile *pg = fd->data;
823 return pg->etag;
811 } 824 }
812 825
813 /* -------------------------- VFS_DIRIO functions -------------------------- */ 826 /* -------------------------- VFS_DIRIO functions -------------------------- */
814 827
815 static int load_dir(VFSDir *dir, PgDir *pg) { 828 static int load_dir(VFSDir *dir, PgDir *pg) {

mercurial