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 {
|
pub fn set(self: *Self, key: []const u8, value: []const u8) void {
|
||||||
const key_len = @intCast(i32, key.len);
|
const key_len = @intCast(i32, key.len);
|
||||||
const value_len = @intCast(i32, value.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);
|
_ = 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 {
|
pub fn append(self: *Self, key: []const u8, value: []const u8, delim: []const u8) void {
|
||||||
const key_len = @intCast(i32, key.len);
|
const key_len = @intCast(i32, key.len);
|
||||||
const value_len = @intCast(i32, value.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;
|
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
|
/// Generic function to find occurences of a string inside another one with delimiters
|
||||||
fn isInStringDelim(haystack: []const u8, needle: []const u8, delim: u8) bool {
|
fn isInStringDelim(haystack: []const u8, needle: []const u8, delim: u8) bool {
|
||||||
var spliter = std.mem.split(u8, haystack, &[_]u8{delim});
|
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 {
|
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:----".*;
|
var item_sel = "item:----".*;
|
||||||
std.mem.copy(u8, item_sel[5..], id[0..]);
|
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{
|
return Self{
|
||||||
.id = aid,
|
.id = aid,
|
||||||
.tags = tags,
|
.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, "");
|
var db = Db.open("test.tkh", true, "");
|
||||||
|
|
||||||
|
// ---------------------- ADD ---------------------------
|
||||||
|
|
||||||
const jsonText: [:0]const u8 =
|
const jsonText: [:0]const u8 =
|
||||||
\\{ "add" : [
|
\\{ "add" : [
|
||||||
\\ [
|
\\ [
|
||||||
|
@ -44,6 +46,19 @@ pub fn main() !void {
|
||||||
|
|
||||||
std.debug.print("\n\n", .{});
|
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 =
|
const jsonQuery: [:0]const u8 =
|
||||||
\\{ "query" : "fur made_with:krita date:2022", "limit" : 20 }
|
\\{ "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);
|
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 {
|
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 {
|
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();
|
const query_str = jobj.getString();
|
||||||
var jret = json.Obj.newArray();
|
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);
|
var id_iter = util.intersection(ids.items);
|
||||||
while (id_iter.next()) |item_id| {
|
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());
|
jret.arrayAdd(&item.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
return jret;
|
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