--- 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(¶ms, 0, newparent)
+ || evsql_param_string(¶ms, 1, newname)
+ || evsql_param_uint32(¶ms, 2, parent)
+ || evsql_param_string(¶ms, 3, name)
+ )
+ SERROR(err = EIO);
+
+ // query
+ if (evsql_query_params(dbfs_ctx->db, NULL, sql, ¶ms, 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;