# HG changeset patch # User Tero Marttila # Date 1224260907 -10800 # Node ID 460f995d3769d90e68e812fe26fb2102e971f3a5 # Parent c71f3053c7148ee1afc9f275dd5b42ed7cd0197f fix readdir to use ORDER BY, rename diff -r c71f3053c714 -r 460f995d3769 Makefile --- 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} diff -r c71f3053c714 -r 460f995d3769 src/dbfs/common.c --- 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; diff -r c71f3053c714 -r 460f995d3769 src/dbfs/dbfs.c --- 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, diff -r c71f3053c714 -r 460f995d3769 src/dbfs/dirop.c --- 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) { diff -r c71f3053c714 -r 460f995d3769 src/dbfs/link.c --- 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); } + diff -r c71f3053c714 -r 460f995d3769 src/dbfs/ops.h --- 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); diff -r c71f3053c714 -r 460f995d3769 src/dbfs/tree.c --- /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"); +} diff -r c71f3053c714 -r 460f995d3769 src/evsql.h --- 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); diff -r c71f3053c714 -r 460f995d3769 src/evsql/util.c --- 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 #include #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;