126 static const char *sql_create_collection = |
126 static const char *sql_create_collection = |
127 "insert into Resource (parent_id, nodename, iscollection, lastmodified, creationdate, contentlength) values\n\ |
127 "insert into Resource (parent_id, nodename, iscollection, lastmodified, creationdate, contentlength) values\n\ |
128 ($1, $2, true, now(), now(), 0)\n\ |
128 ($1, $2, true, now(), now(), 0)\n\ |
129 returning resource_id, lastmodified, creationdate;"; |
129 returning resource_id, lastmodified, creationdate;"; |
130 |
130 |
|
131 // Update resource metadata |
|
132 // params: $1: resource_id |
|
133 // $2: contentlength |
|
134 static const char *sql_update_resource = "update Resource set contentlength = $2, lastmodified = now() where resource_id = $1;"; |
|
135 |
131 VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb) { |
136 VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb) { |
132 // resourcepool is required |
137 // resourcepool is required |
133 char *resource_pool = pblock_findval("resourcepool", pb); |
138 char *resource_pool = pblock_findval("resourcepool", pb); |
134 if(!resource_pool) { |
139 if(!resource_pool) { |
135 log_ereport(LOG_MISCONFIG, "pg_vfs_create: missing resourcepool parameter"); |
140 log_ereport(LOG_MISCONFIG, "pg_vfs_create: missing resourcepool parameter"); |
453 } |
458 } |
454 |
459 |
455 return ret; |
460 return ret; |
456 } |
461 } |
457 |
462 |
|
463 int pg_update_resource(PgVFS *pg, int64_t resource_id, int64_t contentlength) { |
|
464 char resid_str[32]; |
|
465 char ctlen_str[32]; |
|
466 snprintf(resid_str, 32, "%" PRId64, resource_id); |
|
467 snprintf(ctlen_str, 32, "%" PRId64, contentlength); |
|
468 |
|
469 const char* params[2] = { resid_str, ctlen_str }; |
|
470 PGresult *result = PQexecParams( |
|
471 pg->connection, |
|
472 sql_update_resource, |
|
473 2, // number of parameters |
|
474 NULL, |
|
475 params, // parameter value |
|
476 NULL, |
|
477 NULL, |
|
478 0); // 0: result in text format |
|
479 |
|
480 int ret = PQresultStatus(result) == PGRES_COMMAND_OK ? 0 : 1; |
|
481 PQclear(result); |
|
482 return ret; |
|
483 } |
|
484 |
458 /* -------------------------- VFS functions -------------------------- */ |
485 /* -------------------------- VFS functions -------------------------- */ |
459 |
486 |
460 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags) { |
487 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags) { |
461 VFS *vfs = ctx->vfs; |
488 VFS *vfs = ctx->vfs; |
462 PgVFS *pg = vfs->instance; |
489 PgVFS *pg = vfs->instance; |
646 return lo_tell64(pgvfs->connection, pg->fd); |
674 return lo_tell64(pgvfs->connection, pg->fd); |
647 } |
675 } |
648 |
676 |
649 void pg_vfs_io_close(SYS_FILE fd) { |
677 void pg_vfs_io_close(SYS_FILE fd) { |
650 pool_handle_t *pool = fd->ctx->pool; |
678 pool_handle_t *pool = fd->ctx->pool; |
|
679 PgVFS *pgvfs = fd->ctx->vfs->instance; |
651 PgFile *pg = fd->data; |
680 PgFile *pg = fd->data; |
652 |
681 |
653 if(pg->fd >= 0) { |
682 if(pg->fd >= 0) { |
|
683 if((pg->oflags & (O_WRONLY|O_RDWR)) > 0) { |
|
684 // file modified, update length and lastmodified |
|
685 off_t len = pg_vfs_io_seek(fd, 0, SEEK_END); |
|
686 if(len < 0) len = 0; |
|
687 |
|
688 pg_update_resource(pgvfs, pg->resource_id, len); |
|
689 } |
|
690 |
654 PgVFS *pgvfs = fd->ctx->vfs->instance; |
691 PgVFS *pgvfs = fd->ctx->vfs->instance; |
655 lo_close(pgvfs->connection, pg->fd); |
692 lo_close(pgvfs->connection, pg->fd); |
656 } |
693 } |
657 |
694 |
658 pool_free(pool, pg); |
695 pool_free(pool, pg); |