Implement item deletion
This commit is contained in:
parent
b603972a40
commit
4d9f3e32e2
30
src/Db.zig
30
src/Db.zig
|
@ -64,7 +64,7 @@ pub fn open(path: [:0]const u8, writable: bool, params: [:0]const u8) Self {
|
|||
};
|
||||
}
|
||||
|
||||
// TODO: Returrn error
|
||||
// TODO: Return error
|
||||
pub fn set(self: *Self, key: []const u8, value: []const u8) void {
|
||||
const key_len = @intCast(i32, key.len);
|
||||
const value_len = @intCast(i32, value.len);
|
||||
|
@ -72,7 +72,12 @@ pub fn set(self: *Self, key: []const u8, value: []const u8) void {
|
|||
_ = c.tkrzw_dbm_set(self.dbm, key.ptr, key_len, value.ptr, value_len, true);
|
||||
}
|
||||
|
||||
// TODO: Returrn error
|
||||
// TODO: Return error
|
||||
pub fn remove(self: *Self, key: []const u8) bool {
|
||||
return c.tkrzw_dbm_remove(self.dbm, key.ptr, @intCast(i32, key.len));
|
||||
}
|
||||
|
||||
// TODO: Return error
|
||||
pub fn append(self: *Self, key: []const u8, value: []const u8, delim: []const u8) void {
|
||||
const key_len = @intCast(i32, key.len);
|
||||
const value_len = @intCast(i32, value.len);
|
||||
|
@ -126,6 +131,27 @@ pub fn isInList(self: *Self, key: []const u8, needle: []const u8) bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: Return wether or not the list is void after this
|
||||
pub fn removeFromList(self: *Self, key: []const u8, needle: []const u8) void {
|
||||
// TODO: Better error handling, do not fail silently
|
||||
const haystack = self.get(key) orelse return;
|
||||
|
||||
// If there's no start, somesthing's wrong
|
||||
const start = std.mem.indexOf(u8, haystack, needle) orelse return;
|
||||
const end = start + needle.len;
|
||||
|
||||
// Re-set the rest of the IDs
|
||||
self.set(key, haystack[0..start]);
|
||||
|
||||
// We were deleting the last in the list, no need to append anything
|
||||
if (end >= haystack.len) return;
|
||||
|
||||
// +1 to remove the space
|
||||
self.append(key, haystack[(end + 1)..], " ");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// Generic function to find occurences of a string inside another one with delimiters
|
||||
fn isInStringDelim(haystack: []const u8, needle: []const u8, delim: u8) bool {
|
||||
var spliter = std.mem.split(u8, haystack, &[_]u8{delim});
|
||||
|
|
33
src/Item.zig
33
src/Item.zig
|
@ -110,7 +110,39 @@ pub fn persist(self: *Self, db: *Db, allocator: std.mem.Allocator) !void {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Return error or something, check for it
|
||||
pub fn delete(self: Self, db: *Db) !void {
|
||||
// TODO: Throw proper error
|
||||
const id = self.id orelse return;
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
// Delete the id inside the tags
|
||||
if (self.tags) |tags| {
|
||||
for (tags) |tag| {
|
||||
// Get the tag selector: "tag:<tag>"
|
||||
// TODO: Put this inside a function so is is comfier
|
||||
const tag_sel = try std.mem.concat(allocator, u8, &[_][]const u8{ "tag:", tag });
|
||||
defer allocator.free(tag_sel);
|
||||
|
||||
// TODO: See what to do when the tag doesn't exist
|
||||
// TODO: Grab when it's the last of that tag
|
||||
db.removeFromList(tag_sel, tag);
|
||||
}
|
||||
}
|
||||
|
||||
var item_sel = "item:----".*;
|
||||
std.mem.copy(u8, item_sel[5..], id[0..]);
|
||||
|
||||
// Finally delete the item per se
|
||||
// TODO: Return error on error
|
||||
_ = db.remove(&item_sel);
|
||||
}
|
||||
|
||||
pub fn getById(id: []const u8, db: *Db, allocator: std.mem.Allocator) !?Self {
|
||||
// TODO: Create a function that returns the selector
|
||||
var item_sel = "item:----".*;
|
||||
std.mem.copy(u8, item_sel[5..], id[0..]);
|
||||
|
||||
|
@ -122,6 +154,7 @@ pub fn getById(id: []const u8, db: *Db, allocator: std.mem.Allocator) !?Self {
|
|||
return Self{
|
||||
.id = aid,
|
||||
.tags = tags,
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
15
src/main.zig
15
src/main.zig
|
@ -10,6 +10,8 @@ pub fn main() !void {
|
|||
|
||||
var db = Db.open("test.tkh", true, "");
|
||||
|
||||
// ---------------------- ADD ---------------------------
|
||||
|
||||
const jsonText: [:0]const u8 =
|
||||
\\{ "add" : [
|
||||
\\ [
|
||||
|
@ -44,6 +46,19 @@ pub fn main() !void {
|
|||
|
||||
std.debug.print("\n\n", .{});
|
||||
|
||||
// -------------------- DELETE --------------------------
|
||||
|
||||
const jsonDelete: [:0]const u8 =
|
||||
\\{ "delete" : [ "0000", "0003" ] }
|
||||
;
|
||||
|
||||
var jdelete = json.Obj.newFromString(jsonDelete);
|
||||
defer jdelete.deinit();
|
||||
|
||||
try request.process(&jdelete, &db);
|
||||
|
||||
// -------------------- QUERY ---------------------------
|
||||
|
||||
const jsonQuery: [:0]const u8 =
|
||||
\\{ "query" : "fur made_with:krita date:2022", "limit" : 20 }
|
||||
;
|
||||
|
|
|
@ -25,7 +25,12 @@ pub fn process(jobj: *json.Obj, db: *Db) !void {
|
|||
jret.objectAdd("queried", &ret);
|
||||
}
|
||||
|
||||
std.debug.print("{s}", .{jret.toString()});
|
||||
if (jobj.objectGet("delete") catch null) |*jaction| {
|
||||
var ret = try delete(jaction, db, allocator);
|
||||
jret.objectAdd("deleted", &ret);
|
||||
}
|
||||
|
||||
std.debug.print("{s}\n", .{jret.toString()});
|
||||
}
|
||||
|
||||
pub fn add(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||
|
@ -53,6 +58,8 @@ pub fn add(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
|||
}
|
||||
|
||||
pub fn query(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||
// TODO: Have into account limits so it is scalable
|
||||
// TODO: Do not fetch EVERY id at once, iterate where possible
|
||||
const query_str = jobj.getString();
|
||||
var jret = json.Obj.newArray();
|
||||
|
||||
|
@ -81,10 +88,31 @@ pub fn query(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
|||
|
||||
var id_iter = util.intersection(ids.items);
|
||||
while (id_iter.next()) |item_id| {
|
||||
const item = (try Item.getById(item_id, db, allocator)) orelse continue;
|
||||
var item = (try Item.getById(item_id, db, allocator)) orelse continue;
|
||||
defer item.deinit();
|
||||
|
||||
jret.arrayAdd(&item.toJson());
|
||||
}
|
||||
|
||||
return jret;
|
||||
}
|
||||
|
||||
pub fn delete(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||
var jret = json.Obj.newArray();
|
||||
|
||||
// Go over each tag
|
||||
var id_iter = jobj.arrayGetIterator();
|
||||
while (id_iter.next()) |*jid| {
|
||||
const id = jid.getString();
|
||||
|
||||
// TODO: Return some kind of error or somethign telling that some were not found
|
||||
var item = (try Item.getById(id, db, allocator)) orelse continue;
|
||||
defer item.deinit();
|
||||
|
||||
jret.arrayAdd(&item.toJson());
|
||||
|
||||
try item.delete(db);
|
||||
}
|
||||
|
||||
return jret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue