Compare commits

..

No commits in common. "29338ca02b235046f2c1f5086cb267e8c319ffa0" and "b5fa6960ef4a51d3ade83d53bb1cd8aed9bf52b0" have entirely different histories.

5 changed files with 28 additions and 124 deletions

View file

@ -32,7 +32,7 @@ bookmarkctl - manage a mounted BookmarkFS filesystem
.B bookmarkctl .B bookmarkctl
.B xattr\-get .B xattr\-get
.RI [ options ] .RI [ options ]
.B \-a .B \-m
.IR attrname "... " pathname .IR attrname "... " pathname
.PP .PP
.B bookmarkctl .B bookmarkctl
@ -145,7 +145,7 @@ Treat the value as binary, and print it verbatim.
.IP .IP
If this option is not provided, non-printable characters are replaced with '?'. If this option is not provided, non-printable characters are replaced with '?'.
.TP .TP
.B \-a .B \-m
Switch to multi-attrname mode, where multiple extended attribute names Switch to multi-attrname mode, where multiple extended attribute names
can be specified instead of multiple files. can be specified instead of multiple files.
.IP .IP

View file

@ -630,7 +630,7 @@ Displays extended attribute values.
@example @example
bookmarkctl xattr-get [@var{options}] @var{attrname} @var{pathname}... bookmarkctl xattr-get [@var{options}] @var{attrname} @var{pathname}...
bookmarkctl xattr-get [@var{options}] -a @var{attrname}... @var{pathname} bookmarkctl xattr-get [@var{options}] -m @var{attrname}... @var{pathname}
@end example @end example
@table @var @table @var
@ -650,7 +650,7 @@ Treat the value as binary, and print it verbatim.
If this option is not provided, non-printable characters are replaced with If this option is not provided, non-printable characters are replaced with
@samp{?}. @samp{?}.
@item -a @item -m
Switch to multi-attrname mode, where multiple extended attribute names Switch to multi-attrname mode, where multiple extended attribute names
can be specified instead of multiple files. can be specified instead of multiple files.

View file

@ -133,14 +133,11 @@ enum {
STMT_MOZBM_MTIME_UPDATE, STMT_MOZBM_MTIME_UPDATE,
STMT_MOZBM_POS_SHIFT, STMT_MOZBM_POS_SHIFT,
STMT_MOZBM_POS_UPDATE, STMT_MOZBM_POS_UPDATE,
STMT_MOZBM_PURGE,
STMT_MOZBM_PURGE_CHECK,
STMT_MOZBM_UPDATE, STMT_MOZBM_UPDATE,
STMT_MOZBMDEL_INSERT, STMT_MOZBMDEL_INSERT,
STMT_MOZKW_DELETE, STMT_MOZKW_DELETE,
STMT_MOZKW_INSERT, STMT_MOZKW_INSERT,
STMT_MOZKW_LOOKUP, STMT_MOZKW_LOOKUP,
STMT_MOZKW_PURGE,
STMT_MOZKW_RENAME, STMT_MOZKW_RENAME,
STMT_TAG_ENTRY_LOOKUP, STMT_TAG_ENTRY_LOOKUP,
#endif /* defined(BOOKMARKFS_BACKEND_FIREFOX_WRITE) */ #endif /* defined(BOOKMARKFS_BACKEND_FIREFOX_WRITE) */
@ -291,7 +288,7 @@ static bool is_valid_guid (char const *, size_t);
static int keyword_create (struct backend_ctx *, char const *, size_t, static int keyword_create (struct backend_ctx *, char const *, size_t,
struct bookmarkfs_bookmark_stat *); struct bookmarkfs_bookmark_stat *);
static int mozbm_check_cb (void *, sqlite3_stmt *); static int mozbm_check_cb (void *, sqlite3_stmt *);
static int mozbm_delete (struct backend_ctx *, int64_t, bool, bool); static int mozbm_delete (struct backend_ctx *, int64_t, bool);
static int mozbm_delete_cb (void *, sqlite3_stmt *); static int mozbm_delete_cb (void *, sqlite3_stmt *);
static int mozbm_get_title (struct backend_ctx *, int64_t, int64_t, static int mozbm_get_title (struct backend_ctx *, int64_t, int64_t,
db_query_row_func *, void *); db_query_row_func *, void *);
@ -305,14 +302,11 @@ static int mozbm_mtime_update (struct backend_ctx *, int64_t, int64_t *);
static int mozbm_pos_shift (struct backend_ctx *, int64_t, int64_t, static int mozbm_pos_shift (struct backend_ctx *, int64_t, int64_t,
int64_t *, enum bookmarkfs_permd_op); int64_t *, enum bookmarkfs_permd_op);
static int mozbm_pos_update (struct backend_ctx *, int64_t, int64_t); static int mozbm_pos_update (struct backend_ctx *, int64_t, int64_t);
static int mozbm_purge (struct backend_ctx *, int64_t);
static int mozbm_purge_check (struct backend_ctx *, int64_t);
static int mozbm_update (struct backend_ctx *, struct mozbm *); static int mozbm_update (struct backend_ctx *, struct mozbm *);
static int mozbmdel_insert (struct backend_ctx *, char const *); static int mozbmdel_insert (struct backend_ctx *, char const *);
static int mozkw_delete (struct backend_ctx *, char const *, size_t); static int mozkw_delete (struct backend_ctx *, char const *, size_t);
static int mozkw_insert (struct backend_ctx *, struct mozkw *); static int mozkw_insert (struct backend_ctx *, struct mozkw *);
static int mozkw_lookup (struct backend_ctx *, struct mozkw *); static int mozkw_lookup (struct backend_ctx *, struct mozkw *);
static int mozkw_purge (struct backend_ctx *, int64_t);
static int mozkw_rename (struct backend_ctx *, char const *, static int mozkw_rename (struct backend_ctx *, char const *,
char const *, uint32_t); char const *, uint32_t);
static int mozorigin_delete (struct backend_ctx *, int64_t); static int mozorigin_delete (struct backend_ctx *, int64_t);
@ -324,9 +318,8 @@ static int mozplace_addref (struct backend_ctx *, char const *, size_t,
static int mozplace_addref_cb (void *, sqlite3_stmt *); static int mozplace_addref_cb (void *, sqlite3_stmt *);
static int mozplace_addref_id (struct backend_ctx *, int64_t); static int mozplace_addref_id (struct backend_ctx *, int64_t);
static int mozplace_delete (struct backend_ctx *, int64_t, int64_t); static int mozplace_delete (struct backend_ctx *, int64_t, int64_t);
static int mozplace_delref (struct backend_ctx *, int64_t, int); static int mozplace_delref (struct backend_ctx *, int64_t);
static int mozplace_insert (struct backend_ctx *, struct mozplace *); static int mozplace_insert (struct backend_ctx *, struct mozplace *);
static int mozplace_purge (struct backend_ctx *, int64_t);
static int mozplace_update (struct backend_ctx *, struct mozplace *); static int mozplace_update (struct backend_ctx *, struct mozplace *);
static int64_t mozplace_url_hash (char const *, size_t); static int64_t mozplace_url_hash (char const *, size_t);
static int parse_mkfsopts (struct bookmarkfs_conf_opt const *, static int parse_mkfsopts (struct bookmarkfs_conf_opt const *,
@ -464,7 +457,7 @@ bookmark_do_delete (
return is_dir ? -ENOTDIR : -EISDIR; return is_dir ? -ENOTDIR : -EISDIR;
} }
status = mozbm_delete(ctx, cols.id, is_dir, true); status = mozbm_delete(ctx, cols.id, is_dir);
if (status < 0) { if (status < 0) {
return status; return status;
} }
@ -682,8 +675,7 @@ static int
mozbm_delete ( mozbm_delete (
struct backend_ctx *ctx, struct backend_ctx *ctx,
int64_t id, int64_t id,
bool is_dir, bool is_dir
bool purge
) { ) {
#define MOZBM_DELETE_(cond) \ #define MOZBM_DELETE_(cond) \
"DELETE FROM `moz_bookmarks` WHERE `id` = ? " cond \ "DELETE FROM `moz_bookmarks` WHERE `id` = ? " cond \
@ -715,7 +707,7 @@ mozbm_delete (
// The ID is alwayed obtained from a previous query in // The ID is alwayed obtained from a previous query in
// the same transaction. This shall not happen. // the same transaction. This shall not happen.
xassert(nrows > 0); xassert(nrows > 0);
int status = mozplace_delref(ctx, qctx.place_id, purge ? 0 : 1); int status = mozplace_delref(ctx, qctx.place_id);
if (status < 0) { if (status < 0) {
return status; return status;
} }
@ -1028,45 +1020,6 @@ mozbm_pos_update (
return 1; return 1;
} }
static int
mozbm_purge (
struct backend_ctx *ctx,
int64_t place_id
) {
sqlite3_stmt **stmt_ptr = &ctx->stmts[STMT_MOZBM_PURGE];
char const *sql = "DELETE FROM `moz_bookmarks` WHERE `fk` = ?";
int status;
DO_QUERY(ctx, stmt_ptr, sql, NULL, NULL, status, , ,
DB_QUERY_BIND_INT64(place_id),
);
if (status < 0) {
return status;
}
return sqlite3_changes(ctx->db);
}
static int
mozbm_purge_check (
struct backend_ctx *ctx,
int64_t place_id
) {
sqlite3_stmt **stmt_ptr = &ctx->stmts[STMT_MOZBM_PURGE_CHECK];
char const *sql = "SELECT COUNT(*) FROM `moz_bookmarks` "
"WHERE `fk` = ? AND `title` IS NOT NULL";
int64_t result;
ssize_t nrows;
DO_QUERY(ctx, stmt_ptr, sql, db_query_i64_cb, &result, nrows, , ,
DB_QUERY_BIND_INT64(place_id),
);
if (nrows < 0) {
return nrows;
}
debug_assert(nrows == 1);
return result == 0;
}
static int static int
mozbm_update ( mozbm_update (
struct backend_ctx *ctx, struct backend_ctx *ctx,
@ -1145,7 +1098,7 @@ mozkw_delete (
if (status < 0) { if (status < 0) {
return status; return status;
} }
status = mozplace_delref(ctx, place_id, 1); status = mozplace_delref(ctx, place_id);
if (status < 0) { if (status < 0) {
return status; return status;
} }
@ -1200,24 +1153,6 @@ mozkw_lookup (
return 0; return 0;
} }
static int
mozkw_purge (
struct backend_ctx *ctx,
int64_t place_id
) {
sqlite3_stmt **stmt_ptr = &ctx->stmts[STMT_MOZKW_PURGE];
char const *sql = "DELETE FROM `moz_keywords` WHERE `place_id` = ?";
int status;
DO_QUERY(ctx, stmt_ptr, sql, NULL, NULL, status, , ,
DB_QUERY_BIND_INT64(place_id),
);
if (status < 0) {
return status;
}
return sqlite3_changes(ctx->db);
}
static int static int
mozkw_rename ( mozkw_rename (
struct backend_ctx *ctx, struct backend_ctx *ctx,
@ -1238,7 +1173,7 @@ mozkw_rename (
if (flags & BOOKMARKFS_BOOKMARK_RENAME_NOREPLACE) { if (flags & BOOKMARKFS_BOOKMARK_RENAME_NOREPLACE) {
return -EEXIST; return -EEXIST;
} }
status = mozplace_delref(ctx, old_cols.place_id, 1); status = mozplace_delref(ctx, old_cols.place_id);
if (status < 0) { if (status < 0) {
return status; return status;
} }
@ -1477,18 +1412,16 @@ mozplace_delete (
static int static int
mozplace_delref ( mozplace_delref (
struct backend_ctx *ctx, struct backend_ctx *ctx,
int64_t id, int64_t id
int purge
) { ) {
sqlite3_stmt **stmt_ptr = &ctx->stmts[STMT_MOZPLACE_DELREF]; sqlite3_stmt **stmt_ptr = &ctx->stmts[STMT_MOZPLACE_DELREF];
char const *sql = char const *sql =
"UPDATE `moz_places` SET `foreign_count` = `foreign_count` - ? " "UPDATE `moz_places` SET `foreign_count` = `foreign_count` - 1 "
"WHERE `id` = ? RETURNING `foreign_count`, `origin_id`"; "WHERE `id` = ? RETURNING `foreign_count`, `origin_id`";
ssize_t nrows; ssize_t nrows;
int64_t result[2]; // `foreign_count`, `origin_id` int64_t result[2]; // `foreign_count`, `origin_id`
DO_QUERY(ctx, stmt_ptr, sql, db_query_i64_cb, result, nrows, , , DO_QUERY(ctx, stmt_ptr, sql, db_query_i64_cb, result, nrows, , ,
DB_QUERY_BIND_INT64(purge == 0 ? 1 : purge),
DB_QUERY_BIND_INT64(id), DB_QUERY_BIND_INT64(id),
); );
if (nrows < 0) { if (nrows < 0) {
@ -1497,14 +1430,11 @@ mozplace_delref (
if (unlikely(nrows == 0)) { if (unlikely(nrows == 0)) {
return -EIO; return -EIO;
} }
if (result[0] == 0) { if (result[0] > 0) {
// `foreign_count` reaches 0, delete row.
return mozplace_delete(ctx, id, result[1]);
}
if (purge > 0) {
return 0; return 0;
} }
return mozplace_purge(ctx, id); // `foreign_count` reaches 0, delete row.
return mozplace_delete(ctx, id, result[1]);
} }
static int static int
@ -1539,33 +1469,6 @@ mozplace_insert (
return 0; return 0;
} }
static int
mozplace_purge (
struct backend_ctx *ctx,
int64_t id
) {
int status = mozbm_purge_check(ctx, id);
if (status <= 0) {
return status;
}
status = mozbm_purge(ctx, id);
if (status < 0) {
return status;
}
int changes = status;
status = mozkw_purge(ctx, id);
if (status < 0) {
return status;
}
changes += status;
if (changes == 0) {
return 0;
}
return mozplace_delref(ctx, id, changes);
}
static int static int
mozplace_update ( mozplace_update (
struct backend_ctx *ctx, struct backend_ctx *ctx,
@ -1579,7 +1482,7 @@ mozplace_update (
if (status < 0) { if (status < 0) {
return status; return status;
} }
status = mozplace_delref(ctx, cols->id, 1); status = mozplace_delref(ctx, cols->id);
if (status < 0) { if (status < 0) {
return status; return status;
} }
@ -2097,7 +2000,7 @@ tag_entry_delete (
return status; return status;
} }
status = mozbm_delete(ctx, cols.id, false, false); status = mozbm_delete(ctx, cols.id, false);
if (status < 0) { if (status < 0) {
return status; return status;
} }
@ -2272,7 +2175,8 @@ bookmark_do_list (
"SELECT min(`b`.`id`), `k`.`id`, `k`.`keyword`" cols " " \ "SELECT min(`b`.`id`), `k`.`id`, `k`.`keyword`" cols " " \
"FROM `moz_keywords` `k` " join \ "FROM `moz_keywords` `k` " join \
"JOIN `moz_bookmarks` `b` ON `k`.`place_id` = `b`.`fk` " \ "JOIN `moz_bookmarks` `b` ON `k`.`place_id` = `b`.`fk` " \
"WHERE `k`.`id` >= ?2 GROUP BY `k`.`place_id` ORDER BY `k`.`id`" "WHERE `k`.`id` >= ?2 AND `b`.`title` IS NOT NULL " \
"GROUP BY `k`.`place_id` ORDER BY `k`.`id`"
#define BOOKMARK_LIST_KEYWORD BOOKMARK_LIST_KEYWORD_(,) #define BOOKMARK_LIST_KEYWORD BOOKMARK_LIST_KEYWORD_(,)
#define BOOKMARK_LIST_KEYWORD_EX \ #define BOOKMARK_LIST_KEYWORD_EX \
BOOKMARK_LIST_KEYWORD_(", " BOOKMARK_LIST_EX_COLS_, \ BOOKMARK_LIST_KEYWORD_(", " BOOKMARK_LIST_EX_COLS_, \
@ -2364,7 +2268,8 @@ bookmark_do_lookup (
#define PLACE_ID_BY_KEYWORD(val) \ #define PLACE_ID_BY_KEYWORD(val) \
"SELECT `place_id` FROM `moz_keywords` WHERE `keyword` = " val "SELECT `place_id` FROM `moz_keywords` WHERE `keyword` = " val
#define BOOKMARK_LOOKUP_PLACE_ID_(val) \ #define BOOKMARK_LOOKUP_PLACE_ID_(val) \
BOOKMARK_LOOKUP_(, "`b`.`fk` = " val " ORDER BY `b`.`id` LIMIT 1") BOOKMARK_LOOKUP_(, "`b`.`fk` = " val " AND `b`.`title` IS NOT NULL " \
"ORDER BY `b`.`id` LIMIT 1")
#define BOOKMARK_LOOKUP_KEYWORD_(val) \ #define BOOKMARK_LOOKUP_KEYWORD_(val) \
BOOKMARK_LOOKUP_PLACE_ID_("(" PLACE_ID_BY_KEYWORD(val) ")") BOOKMARK_LOOKUP_PLACE_ID_("(" PLACE_ID_BY_KEYWORD(val) ")")
#define BOOKMARK_LOOKUP_KEYWORD BOOKMARK_LOOKUP_KEYWORD_("?2") #define BOOKMARK_LOOKUP_KEYWORD BOOKMARK_LOOKUP_KEYWORD_("?2")
@ -3714,7 +3619,7 @@ bookmark_rename (
status = (old_cols.place_id == 0) ? -ENOTDIR : -EISDIR; status = (old_cols.place_id == 0) ? -ENOTDIR : -EISDIR;
goto fail; goto fail;
} }
status = mozbm_delete(ctx, new_cols.id, old_cols.place_id == 0, true); status = mozbm_delete(ctx, new_cols.id, old_cols.place_id == 0);
if (status < 0) { if (status < 0) {
goto fail; goto fail;
} }

View file

@ -48,7 +48,7 @@ struct xattr_get_ctx {
char eol; char eol;
unsigned binary : 1; unsigned binary : 1;
unsigned multi_attr : 1; unsigned multi_name : 1;
}; };
// Forward declaration start // Forward declaration start
@ -249,8 +249,8 @@ subcmd_xattr_get (
ctx.binary = 1; ctx.binary = 1;
break; break;
} }
OPT_OPT('a') { OPT_OPT('m') {
ctx.multi_attr = 1; ctx.multi_name = 1;
break; break;
} }
OPT_OPT('q') { OPT_OPT('q') {
@ -269,7 +269,7 @@ subcmd_xattr_get (
return -1; return -1;
} }
if (ctx.multi_attr) { if (ctx.multi_name) {
return xattr_get_one(argv[argc - 1], argv, argc - 1, &ctx); return xattr_get_one(argv[argc - 1], argv, argc - 1, &ctx);
} }
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
@ -416,7 +416,7 @@ xattr_get_one (
for (int i = 0; i < names_cnt; ++i) { for (int i = 0; i < names_cnt; ++i) {
char const *name = names[i]; char const *name = names[i];
ctx->prefix = ctx->multi_attr ? name : path; ctx->prefix = ctx->multi_name ? name : path;
status = bookmarkfs_xattr_get(fd, name, xattr_get_cb, ctx); status = bookmarkfs_xattr_get(fd, name, xattr_get_cb, ctx);
if (status < 0) { if (status < 0) {
goto end; goto end;

View file

@ -57,7 +57,6 @@ ATX_CHECK_FS_NEW_ASSOC([eol], , [
test ! -e "$atx_tags/$tag-2/$name-3" test ! -e "$atx_tags/$tag-2/$name-3"
test ! -e "$atx_tags/$tag-3/$name-1" test ! -e "$atx_tags/$tag-3/$name-1"
test ! -e "$atx_keywords/$keyword-3" test ! -e "$atx_keywords/$keyword-3"
rmdir "$atx_tags/$tag-1" "$atx_tags/$tag-2" "$atx_tags/$tag-3"
]) ])
]) ])
]) ])