fix readdir to use ORDER BY, rename
authorTero Marttila <terom@fixme.fi>
Fri, 17 Oct 2008 19:28:27 +0300
changeset 34 460f995d3769
parent 33 c71f3053c714
child 35 4f10421681d2
fix readdir to use ORDER BY, rename
Makefile
src/dbfs/common.c
src/dbfs/dbfs.c
src/dbfs/dirop.c
src/dbfs/link.c
src/dbfs/ops.h
src/dbfs/tree.c
src/evsql.h
src/evsql/util.c
--- a/Makefile	Fri Oct 17 18:53:05 2008 +0300
+++ b/Makefile	Fri Oct 17 19:28:27 2008 +0300
@@ -20,7 +20,7 @@
 
 # complex modules
 EVSQL_OBJS = obj/evsql/evsql.o obj/evsql/util.o obj/evpq.o
-DBFS_OBJS = obj/dbfs/dbfs.o obj/dbfs/common.o obj/dbfs/core.o obj/dbfs/op_base.o obj/dbfs/trans.o obj/dbfs/dirop.o obj/dirbuf.o obj/dbfs/fileop.o obj/dbfs/attr.o obj/dbfs/link.o
+DBFS_OBJS = obj/dbfs/dbfs.o obj/dbfs/common.o obj/dbfs/core.o obj/dbfs/op_base.o obj/dbfs/trans.o obj/dbfs/dirop.o obj/dirbuf.o obj/dbfs/fileop.o obj/dbfs/attr.o obj/dbfs/link.o obj/dbfs/tree.o
 
 # first target
 all: ${BIN_PATHS}
--- a/src/dbfs/common.c	Fri Oct 17 18:53:05 2008 +0300
+++ b/src/dbfs/common.c	Fri Oct 17 19:28:27 2008 +0300
@@ -28,7 +28,7 @@
         NERROR(evsql_result_error(res));
         
     // not found?
-    if (evsql_result_rows(res) == 0)
+    if (evsql_result_rows(res) == 0 && evsql_result_affected(res) == 0)
         SERROR(err = 1);
 
     // duplicate rows?
@@ -49,6 +49,8 @@
     return err;
 }
 
+
+
 int _dbfs_stat_info (struct stat *st, const struct evsql_result_info *res, size_t row, size_t col_offset) {
     int err = 0;
     
--- a/src/dbfs/dbfs.c	Fri Oct 17 18:53:05 2008 +0300
+++ b/src/dbfs/dbfs.c	Fri Oct 17 19:28:27 2008 +0300
@@ -17,6 +17,7 @@
     .readlink       = dbfs_readlink,
 
     .symlink        = dbfs_symlink,
+    .rename         = dbfs_rename,
 
     .open           = dbfs_open,
     .read           = dbfs_read,
--- a/src/dbfs/dirop.c	Fri Oct 17 18:53:05 2008 +0300
+++ b/src/dbfs/dirop.c	Fri Oct 17 19:28:27 2008 +0300
@@ -257,6 +257,7 @@
         " file_tree.\"offset\", file_tree.name, inodes.ino, inodes.type"
         " FROM file_tree LEFT OUTER JOIN inodes ON (file_tree.ino = inodes.ino)"
         " WHERE file_tree.parent = $1::int4 AND file_tree.\"offset\" >= $2::int4"
+        " ORDER BY file_tree.\"offset\""
         " LIMIT $3::int4";
 
     static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
--- a/src/dbfs/link.c	Fri Oct 17 18:53:05 2008 +0300
+++ b/src/dbfs/link.c	Fri Oct 17 19:28:27 2008 +0300
@@ -263,3 +263,4 @@
         dbfs_trans_fail(&ctx->base, EIO);
 }
 
+
--- a/src/dbfs/ops.h	Fri Oct 17 18:53:05 2008 +0300
+++ b/src/dbfs/ops.h	Fri Oct 17 19:28:27 2008 +0300
@@ -23,6 +23,9 @@
 void dbfs_readdir (struct fuse_req *req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi);
 void dbfs_releasedir (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi);
 
+/* tree.c */
+void dbfs_rename (struct fuse_req *req, fuse_ino_t parent, const char *name, fuse_ino_t newparent, const char *newname);
+
 /* fileop.c */
 void dbfs_open (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi);
 void dbfs_read (struct fuse_req *req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbfs/tree.c	Fri Oct 17 19:28:27 2008 +0300
@@ -0,0 +1,71 @@
+
+#include "../lib/log.h"
+
+#include "dbfs.h"
+
+void dbfs_rename_res (const struct evsql_result_info *res, void *arg) {
+    struct fuse_req *req = arg;
+    int err;
+
+    // check the results
+    if ((err = _dbfs_check_res(res, 0, 0)))
+        SERROR(err = (err ==  1 ? ENOENT : EIO));
+    
+    // just reply
+    if ((err = -fuse_reply_err(req, 0)))
+        EERROR(err, "fuse_reply_err");
+    
+    // log
+    INFO("[dbfs.rename %p] -> OK", req);
+
+    // fallthrough for result_free
+    err = 0;
+
+error:
+    if (err && (err = -fuse_reply_err(req, err)))
+        EWARNING(err, "fuse_reply_err");
+    
+    evsql_result_free(res);
+}
+
+void dbfs_rename (struct fuse_req *req, fuse_ino_t parent, const char *name, fuse_ino_t newparent, const char *newname) {
+    struct dbfs *dbfs_ctx = fuse_req_userdata(req);
+    int err;
+    
+    INFO("[dbfs.rename %p] parent=%lu, name=%s, newparent=%lu, newname=%s", req, parent, name, newparent, newname);
+
+    // just one UPDATE
+    const char *sql = 
+        "UPDATE"
+        " file_tree"
+        " SET parent = $1::int4, name = $2::varchar"
+        " WHERE parent = $3::int4 AND name = $4::varchar";
+
+    static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
+        EVSQL_PARAM ( UINT32 ),
+        EVSQL_PARAM ( STRING ),
+        EVSQL_PARAM ( UINT32 ),
+        EVSQL_PARAM ( STRING ),
+
+        EVSQL_PARAMS_END
+    };
+
+    if (0
+        ||  evsql_param_uint32(&params, 0, newparent)
+        ||  evsql_param_string(&params, 1, newname)
+        ||  evsql_param_uint32(&params, 2, parent)
+        ||  evsql_param_string(&params, 3, name)
+    )
+        SERROR(err = EIO);
+
+    // query
+    if (evsql_query_params(dbfs_ctx->db, NULL, sql, &params, dbfs_rename_res, req) == NULL)
+        SERROR(err = EIO);
+    
+    // good, wait
+    return;
+
+error:
+    if ((err = fuse_reply_err(req, err)))
+        EWARNING(err, "fuse_reply_err");
+}
--- a/src/evsql.h	Fri Oct 17 18:53:05 2008 +0300
+++ b/src/evsql.h	Fri Oct 17 19:28:27 2008 +0300
@@ -240,6 +240,9 @@
 // number of columns in the result
 size_t evsql_result_cols (const struct evsql_result_info *res);
 
+// number of affected rows for UPDATE/INSERT
+size_t evsql_result_affected (const struct evsql_result_info *res);
+
 // fetch the raw binary value from a result set, and return it via ptr
 // if size is nonzero, check that the size of the field data matches
 int evsql_result_binary (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t *size, int nullok);
--- a/src/evsql/util.c	Fri Oct 17 18:53:05 2008 +0300
+++ b/src/evsql/util.c	Fri Oct 17 19:28:27 2008 +0300
@@ -1,3 +1,4 @@
+#include <stdlib.h>
 #include <assert.h>
 
 #include "evsql.h"
@@ -149,6 +150,16 @@
     }
 }
 
+size_t evsql_result_affected (const struct evsql_result_info *res) {
+    switch (res->evsql->type) {
+        case EVSQL_EVPQ:
+            return strtol(PQcmdTuples(res->result.pq), NULL, 10);
+
+        default:
+            FATAL("res->evsql->type");
+    }
+}
+
 int evsql_result_binary (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t *size, int nullok) {
     *ptr = NULL;