src/server/plugins/postgresql/vfs.c

branch
webdav
changeset 283
25e5b771677d
parent 282
cfb588e27198
child 284
eab579b8c80d
equal deleted inserted replaced
282:cfb588e27198 283:25e5b771677d
70 "with recursive resolvepath as (\n\ 70 "with recursive resolvepath as (\n\
71 select\n\ 71 select\n\
72 resource_id,\n\ 72 resource_id,\n\
73 parent_id,\n\ 73 parent_id,\n\
74 '' as fullpath,\n\ 74 '' as fullpath,\n\
75 resoid,\n\
75 iscollection,\n\ 76 iscollection,\n\
76 lastmodified,\n\ 77 lastmodified,\n\
77 creationdate,\n\ 78 creationdate,\n\
78 contentlength,\n\ 79 contentlength,\n\
79 regexp_split_to_array($1, '/') as pathelm,\n\ 80 regexp_split_to_array($1, '/') as pathelm,\n\
83 union\n\ 84 union\n\
84 select\n\ 85 select\n\
85 r.resource_id,\n\ 86 r.resource_id,\n\
86 r.parent_id,\n\ 87 r.parent_id,\n\
87 p.fullpath || '/' || r.nodename,\n\ 88 p.fullpath || '/' || r.nodename,\n\
89 r.resoid,\n\
88 r.iscollection,\n\ 90 r.iscollection,\n\
89 r.lastmodified,\n\ 91 r.lastmodified,\n\
90 r.creationdate,\n\ 92 r.creationdate,\n\
91 r.contentlength,\n\ 93 r.contentlength,\n\
92 p.pathelm,\n\ 94 p.pathelm,\n\
93 p.pathdepth + 1\n\ 95 p.pathdepth + 1\n\
94 from Resource r\n\ 96 from Resource r\n\
95 inner join resolvepath p on r.parent_id = p.resource_id\n\ 97 inner join resolvepath p on r.parent_id = p.resource_id\n\
96 where p.pathelm[p.pathdepth+1] = r.nodename\n\ 98 where p.pathelm[p.pathdepth+1] = r.nodename\n\
97 )\n\ 99 )\n\
98 select resource_id, parent_id, fullpath, iscollection from resolvepath\n\ 100 select resource_id, parent_id, fullpath, resoid, iscollection, lastmodified, creationdate, contentlength from resolvepath\n\
99 where fullpath = $1 ;"; 101 where fullpath = $1 ;";
100 102
101 // Same as sql_resolve_path, but it returns the root collection 103 // Same as sql_resolve_path, but it returns the root collection
102 // params: $1: path string (should be '/') 104 // params: $1: path string (should be '/')
103 static const char *sql_get_root = "select resource_id, parent_id, $1 as fullpath, true as iscollection, lastmodified, creationdate, contentlength from Resource where parent_id is null;"; 105 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;";
104 106
105 // Get all children of a specific collection 107 // Get all children of a specific collection
106 // params: $1: parent resource_id 108 // params: $1: parent resource_id
107 static const char *sql_get_children = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength from Resource where parent_id = $1;"; 109 static const char *sql_get_children = "select resource_id, nodename, iscollection, lastmodified, creationdate, contentlength from Resource where parent_id = $1;";
108 110
153 int pg_resolve_path( 155 int pg_resolve_path(
154 VFSContext *ctx, 156 VFSContext *ctx,
155 const char *path, 157 const char *path,
156 int64_t *parent_id, 158 int64_t *parent_id,
157 int64_t *resource_id, 159 int64_t *resource_id,
160 Oid *oid,
158 const char **resource_name, 161 const char **resource_name,
159 WSBool *iscollection, 162 WSBool *iscollection,
160 struct stat *s) 163 struct stat *s)
161 { 164 {
162 // basic path validation 165 // basic path validation
189 NULL, 192 NULL,
190 &path, // parameter value 193 &path, // parameter value
191 NULL, 194 NULL,
192 NULL, 195 NULL,
193 0); // 0: result in text format 196 0); // 0: result in text format
194 197
195 if(pathf) { 198 if(pathf) {
196 free(pathf); 199 free(pathf);
197 } 200 }
198 201
199 if(!result) return 1; 202 if(!result) return 1;
202 //int nfields = PQnfields(result); 205 //int nfields = PQnfields(result);
203 int nrows = PQntuples(result); 206 int nrows = PQntuples(result);
204 if(nrows == 1) { 207 if(nrows == 1) {
205 char *resource_id_str = PQgetvalue(result, 0, 0); 208 char *resource_id_str = PQgetvalue(result, 0, 0);
206 char *parent_id_str = PQgetvalue(result, 0, 1); 209 char *parent_id_str = PQgetvalue(result, 0, 1);
207 char *iscol = PQgetvalue(result, 0, 3); 210 char *iscol = PQgetvalue(result, 0, 4);
208 char *lastmodified = PQgetvalue(result, 0, 4); 211 char *lastmodified = PQgetvalue(result, 0, 5);
209 char *creationdate = PQgetvalue(result, 0, 5); 212 char *creationdate = PQgetvalue(result, 0, 6);
210 char *contentlength = PQgetvalue(result, 0, 6); 213 char *contentlength = PQgetvalue(result, 0, 7);
211 if(resource_id_str && parent_id_str) { 214 if(resource_id_str && parent_id_str) {
212 if(util_strtoint(resource_id_str, resource_id)) { 215 if(util_strtoint(resource_id_str, resource_id)) {
213 ret = 0; // success 216 ret = 0; // success
214 } 217 }
215 // optionally get parent_id 218 // optionally get parent_id
216 util_strtoint(parent_id_str, parent_id); 219 util_strtoint(parent_id_str, parent_id);
220 }
221
222 if(oid) {
223 char *resoid = PQgetvalue(result, 0, 3);
224 int64_t roid;
225 if(resoid && util_strtoint(resoid, &roid)) {
226 *oid = roid;
227 }
217 } 228 }
218 229
219 if(iscollection && iscol) { 230 if(iscollection && iscol) {
220 *iscollection = iscol[0] == 't' ? TRUE : FALSE; 231 *iscollection = iscol[0] == 't' ? TRUE : FALSE;
221 } 232 }
246 if(iscol) { 257 if(iscol) {
247 s->st_mode |= 0x4000; 258 s->st_mode |= 0x4000;
248 } 259 }
249 } 260 }
250 // TODO: lastmodified, creationdate 261 // TODO: lastmodified, creationdate
262 // set some test values != 0
263 s->st_mtime = time(NULL);
264
251 if(contentlength) { 265 if(contentlength) {
252 int64_t len; 266 int64_t len;
253 if(util_strtoint(contentlength, &len)) { 267 if(util_strtoint(contentlength, &len)) {
254 s->st_size = len; 268 s->st_size = len;
255 } 269 }
257 } 271 }
258 272
259 /* -------------------------- VFS functions -------------------------- */ 273 /* -------------------------- VFS functions -------------------------- */
260 274
261 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags) { 275 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags) {
276 VFS *vfs = ctx->vfs;
277 PgVFS *pg = vfs->instance;
278
262 const char *resname; 279 const char *resname;
263 int64_t resource_id, parent_id; 280 int64_t resource_id, parent_id;
264 resource_id = -1; 281 resource_id = -1;
265 parent_id = -1; 282 parent_id = -1;
266 WSBool iscollection; 283 WSBool iscollection;
267 struct stat s; 284 struct stat s;
268 if(pg_resolve_path(ctx, path, &parent_id, &resource_id, &resname, &iscollection, &s)) { 285 Oid oid = 0;
286 if(pg_resolve_path(ctx, path, &parent_id, &resource_id, &oid, &resname, &iscollection, &s)) {
269 return NULL; 287 return NULL;
270 } 288 }
271 289
272 VFSFile *file = pool_malloc(ctx->pool, sizeof(VFSFile)); 290 VFSFile *file = pool_malloc(ctx->pool, sizeof(VFSFile));
273 if(!file) { 291 if(!file) {
277 if(!pgfile) { 295 if(!pgfile) {
278 pool_free(ctx->pool, file); 296 pool_free(ctx->pool, file);
279 return NULL; 297 return NULL;
280 } 298 }
281 299
300 int fd = -1;
301 if(!iscollection) {
302 if (PQstatus(pg->connection) != CONNECTION_OK) {
303 fd = -2;
304 }
305
306 int lo_mode = INV_READ; // TODO: evaluate oflags
307 fd = lo_open(pg->connection, oid, lo_mode);
308 }
309
282 pgfile->iscollection = iscollection; 310 pgfile->iscollection = iscollection;
283 pgfile->resource_id = resource_id; 311 pgfile->resource_id = resource_id;
284 pgfile->parent_id = parent_id; 312 pgfile->parent_id = parent_id;
313 pgfile->oid = oid;
314 pgfile->fd = fd;
285 pgfile->s = s; 315 pgfile->s = s;
286 316
287 file->ctx = ctx; 317 file->ctx = ctx;
288 file->io = iscollection ? &pg_vfs_io_class : &pg_vfs_io_class; 318 file->io = iscollection ? &pg_vfs_io_class : &pg_vfs_io_class;
289 file->fd = -1; 319 file->fd = -1;
294 324
295 int pg_vfs_stat(VFSContext *ctx, const char *path, struct stat *buf) { 325 int pg_vfs_stat(VFSContext *ctx, const char *path, struct stat *buf) {
296 int64_t parent_id, resource_id; 326 int64_t parent_id, resource_id;
297 const char *resname; 327 const char *resname;
298 WSBool iscollection; 328 WSBool iscollection;
299 return pg_resolve_path(ctx, path, &parent_id, &resource_id, &resname, &iscollection, buf); 329 return pg_resolve_path(ctx, path, &parent_id, &resource_id, NULL, &resname, &iscollection, buf);
300 } 330 }
301 331
302 int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) { 332 int pg_vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) {
303 PgFile *pgfile = fd->data; 333 PgFile *pgfile = fd->data;
304 memcpy(buf, &pgfile->s, sizeof(struct stat)); 334 memcpy(buf, &pgfile->s, sizeof(struct stat));
357 387
358 388
359 /* -------------------------- VFS_IO functions -------------------------- */ 389 /* -------------------------- VFS_IO functions -------------------------- */
360 390
361 ssize_t pg_vfs_io_read(SYS_FILE fd, void *buf, size_t nbyte) { 391 ssize_t pg_vfs_io_read(SYS_FILE fd, void *buf, size_t nbyte) {
392 PgVFS *pgvfs = fd->ctx->vfs->instance;
393 PgFile *pg = fd->data;
394 return lo_read(pgvfs->connection, pg->fd, buf, nbyte);
395 }
396
397 ssize_t pg_vfs_io_write(SYS_FILE fd, const void *buf, size_t nbyte) {
398 PgVFS *pgvfs = fd->ctx->vfs->instance;
399
362 return 0; 400 return 0;
363 } 401 }
364 402
365 ssize_t pg_vfs_io_write(SYS_FILE fd, const void *buf, size_t nbyte) { 403 ssize_t pg_vfs_io_pread(SYS_FILE fd, void *buf, size_t nbyte, off_t offset) {
404 PgVFS *pgvfs = fd->ctx->vfs->instance;
405
366 return 0; 406 return 0;
367 } 407 }
368 408
369 ssize_t pg_vfs_io_pread(SYS_FILE fd, void *buf, size_t nbyte, off_t offset) { 409 ssize_t pg_vfs_io_pwrite(SYS_FILE fd, const void *buf, size_t nbyte, off_t offset) {
410 PgVFS *pgvfs = fd->ctx->vfs->instance;
411
370 return 0; 412 return 0;
371 } 413 }
372 414
373 ssize_t pg_vfs_io_pwrite(SYS_FILE fd, const void *buf, size_t nbyte, off_t offset) {
374 return 0;
375 }
376
377 off_t pg_vfs_io_seek(SYS_FILE fd, off_t offset, int whence) { 415 off_t pg_vfs_io_seek(SYS_FILE fd, off_t offset, int whence) {
416 PgVFS *pgvfs = fd->ctx->vfs->instance;
417
378 return 0; 418 return 0;
379 } 419 }
380 420
381 void pg_vfs_io_close(SYS_FILE fd) { 421 void pg_vfs_io_close(SYS_FILE fd) {
382 pool_handle_t *pool = fd->ctx->pool; 422 pool_handle_t *pool = fd->ctx->pool;
383 PgFile *pg = fd->data; 423 PgFile *pg = fd->data;
424
425 if(pg->fd >= 0) {
426 PgVFS *pgvfs = fd->ctx->vfs->instance;
427 lo_close(pgvfs->connection, pg->fd);
428 }
384 429
385 pool_free(pool, pg); 430 pool_free(pool, pg);
386 pool_free(pool, fd); 431 pool_free(pool, fd);
387 } 432 }
388 433

mercurial