Delete unused deps, implement tkrzw and num encode

This commit is contained in:
Dendy 2022-10-31 01:21:34 +01:00
parent 9d9f297ac8
commit 895fc2b359
7 changed files with 174 additions and 108 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
zig-* zig-*
.zigmod .zigmod
deps.zig deps.zig
*.tkh

View File

@ -11,13 +11,13 @@ pub fn build(b: *std.build.Builder) void {
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions(); const mode = b.standardReleaseOptions();
// Import autogenerated zigmod dependencies
const deps = @import("deps.zig");
const exe = b.addExecutable("mgtzm", "src/main.zig"); const exe = b.addExecutable("mgtzm", "src/main.zig");
exe.use_stage1 = true; // for sqlite exe.use_stage1 = true; // for sqlite
deps.addAllTo(exe); // zigmod dependencies
// Add dependencies
exe.linkSystemLibrary("json-c"); exe.linkSystemLibrary("json-c");
exe.linkSystemLibrary("tkrzw"); // TODO: Build statically?
exe.setTarget(target); exe.setTarget(target);
exe.setBuildMode(mode); exe.setBuildMode(mode);
exe.install(); exe.install();

View File

@ -1,78 +1,80 @@
const std = @import("std"); const c = @cImport({
const sqlite = @import("sqlite"); @cInclude("tkrzw_langc.h");
// TODO: Make DB an object so we can just do Self.
// TODO: Wrap into transactions with a .flush() method
const ObjectError = error{
IncompatibleObjectType, // No ?u32 "id" field
};
pub fn getLastId(db: *sqlite.Db) !i64 {
const row = try db.one(
struct {
rowid: i64,
},
"SELECT LAST_INSERT_ROWID();",
.{},
.{},
);
if (row) |row_i| {
return row_i.rowid;
}
return 0;
}
pub fn init() !sqlite.Db {
var db = try sqlite.Db.init(.{
.mode = .{ .File = "/tmp/data.db" },
.open_flags = .{
.write = true,
.create = true,
},
.threading_mode = .MultiThread,
}); });
try migrate(&db); const Self = @This();
return db; const std = @import("std");
pub const free = c.free;
dbm: *c.TkrzwDBM,
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const encode_len = 4;
pub fn numEncode(num: usize) ![encode_len]u8 {
return uintEncode(num, 4, chars);
} }
// TODO: Make a proper migration system. pub fn numDecode(str: []const u8) usize {
fn migrate(db: *sqlite.Db) !void { return uintDecode(str, chars);
try db.exec( }
\\CREATE TABLE IF NOT EXISTS item (
\\ id INTEGER PRIMARY KEY const EncodeError = error{
\\); NumberTooBig,
, };
.{},
.{}, fn uintEncode(num: usize, comptime bufflen: usize, comptime charset: []const u8) ![bufflen]u8 {
); // Check if the number is bigger than the maximum possible number
var pow = comptime std.math.pow(usize, charset.len, bufflen);
try db.exec( if (num >= pow) return EncodeError.NumberTooBig;
\\CREATE TABLE IF NOT EXISTS tag (
\\ name TEXT PRIMARY KEY var buff = [_]u8{charset[0]} ** bufflen;
\\);
, var num_i: usize = num;
.{}, for (buff) |*pos| {
.{}, pow /= charset.len;
); pos.* = charset[@divTrunc(num_i, pow)];
try db.exec( num_i %= pow;
\\CREATE TABLE IF NOT EXISTS item_tag ( }
\\ item INTEGER,
\\ tag TEXT, return buff;
\\ value TEXT, }
\\
\\ PRIMARY KEY (item, tag), fn uintDecode(str: []const u8, comptime charset: []const u8) usize {
\\ var ret: usize = 0;
\\ FOREIGN KEY (item) REFERENCES item(id) ON DELETE CASCADE,
\\ FOREIGN KEY (tag) REFERENCES tag(name) ON DELETE CASCADE ON UPDATE CASCADE for (str) |needle, i| {
\\); for (charset) |blade, j| {
, if (needle == blade) {
.{}, ret += std.math.pow(usize, charset.len, str.len - i - 1) * j;
.{}, break;
); }
}
}
return ret;
}
pub fn open(path: [:0]const u8, writable: bool, params: [:0]const u8) Self {
return Self{
.dbm = c.tkrzw_dbm_open(path, writable, params),
};
}
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);
_ = c.tkrzw_dbm_set(self.dbm, key.ptr, key_len, value.ptr, value_len, true);
}
pub fn get(self: *Self, key: []const u8) []u8 {
const key_len = @intCast(i32, key.len);
var len: i32 = 0;
var ret = c.tkrzw_dbm_get(self.dbm, key.ptr, key_len, &len);
return ret[0..@intCast(usize, len)];
} }

View File

@ -1,43 +1,68 @@
const std = @import("std"); const std = @import("std");
const sqlite = @import("sqlite");
const Db = @import("Db.zig"); const Db = @import("Db.zig");
const Item = @import("Item.zig"); const Item = @import("Item.zig");
const Tag = @import("Tag.zig"); const Tag = @import("Tag.zig");
const json = @import("json.zig"); const json = @import("json.zig");
const request = @import("request.zig"); const request = @import("request.zig");
pub fn main() !void { pub fn main() !void {
var db = try Db.init();
const jsonText: [:0]const u8 = var db = Db.open("test.tkh", true, "");
\\{ "add" : [ db.set("test", "lol");
\\ { db.set("kaka", "jeje");
\\ "fur": "dusk", db.set("kaka", "poop");
\\ "made_with": "krita",
\\ "date": "2022-10-01",
\\ "alunya": null
\\ },{
\\ "fur": "lara",
\\ "made_with": "krita",
\\ "date": "2022-04-08",
\\ "cell-shading": null
\\ },{
\\ "made_with": "ballpoint_pen",
\\ "date": "2022-11-04",
\\ "practice": "",
\\ "pose_practice": null
\\ },{
\\ "fur": "lidiarock1",
\\ "made_with": "krita",
\\ "date": "2022-02-15",
\\ "niko_(oneshot)": null
\\ }
\\] }
;
var jobj = json.Obj.newFromString(jsonText); var str = db.get("test");
defer jobj.deinit(); defer Db.free(str.ptr);
std.debug.print("{s}\n", .{str});
try request.process(&jobj, &db); const num = 69420;
const numch = try Db.numEncode(num);
std.debug.print("{}\n", .{Db.numDecode(numch[0..])});
std.debug.print("{}\n", .{num});
//var db = try Db.init();
//
//const jsonText: [:0]const u8 =
//\\{ "add" : [
//\\ {
//\\ "fur": "dusk",
//\\ "made_with": "krita",
//\\ "date": "2022-10-01",
//\\ "alunya": null
//\\ },{
//\\ "fur": "lara",
//\\ "made_with": "krita",
//\\ "date": "2022-04-08",
//\\ "cell-shading": null
//\\ },{
//\\ "made_with": "ballpoint_pen",
//\\ "date": "2022-11-04",
//\\ "practice": "",
//\\ "pose_practice": null
//\\ },{
//\\ "fur": "lidiarock1",
//\\ "made_with": "krita",
//\\ "date": "2022-02-15",
//\\ "niko_(oneshot)": null
//\\ }
//\\] }
//;
//
//var jobj = json.Obj.newFromString(jsonText);
//defer jobj.deinit();
//
//try request.process(&jobj, &db);
//
//std.debug.print("\n\n", .{});
//
//const jsonQuery: [:0]const u8 =
//\\{ "query" : "niko_(oneshot) made_with:krita -fur:dusk" }
//;
//
//var jquery = json.Obj.newFromString(jsonQuery);
//defer jquery.deinit();
//
//try request.process(&jquery, &db);
} }

View File

@ -15,11 +15,16 @@ pub fn process(jobj: *json.Obj, db: *sqlite.Db) !void {
defer jret.deinit(); defer jret.deinit();
// Test the action to carry and pass the object // Test the action to carry and pass the object
if (jobj.objectGet("add") catch null) |*jadd| { if (jobj.objectGet("add") catch null) |*jaction| {
var ret = try add(jadd, db, allocator); var ret = try add(jaction, db, allocator);
jret.objectAdd("added", &ret); jret.objectAdd("added", &ret);
} }
if (jobj.objectGet("query") catch null) |*jaction| {
var ret = try query(jaction, db, allocator);
jret.objectAdd("queried", &ret);
}
std.debug.print("{s}", .{ jret.toString() }); std.debug.print("{s}", .{ jret.toString() });
} }
@ -46,3 +51,44 @@ pub fn add(jobj: *json.Obj, db: *sqlite.Db, allocator: std.mem.Allocator) !json.
return jret; return jret;
} }
pub fn query(jobj: *json.Obj, db: *sqlite.Db, allocator: std.mem.Allocator) !json.Obj {
_ = db;
var jret = json.Obj.newArray();
const query_string = jobj.getString();
var keywords = std.ArrayList([]const u8).init(allocator);
var sql = std.ArrayList(u8).init(allocator);
try sql.appendSlice("SELECT * FROM item_tag WHERE");
var iter = std.mem.split(u8, query_string, " ");
var i: usize = 0;
while(iter.next()) |tag| {
defer i += 1;
try keywords.append(tag);
// Just put AND between keywords
if (i > 0) {
try sql.appendSlice(" AND");
}
// Exclude tags that start with !
try sql.appendSlice(" tag ");
if (tag[0] == '-') {
try sql.append('!');
}
try sql.appendSlice("= ?");
}
std.debug.print("{s}\n", .{sql.items});
//var stmt = try db.prepareDynamic();
//defer stmt.deinit();
//
return jret;
}

View File

@ -1,2 +0,0 @@
2
git https://github.com/vrischmann/zig-sqlite commit-624bbf60e79c2b6c838e952aa0c8c4cc35128044

View File

@ -1,6 +0,0 @@
id: xstmgop7lwvcrkd18q3u95noqfk3oromr3vixj1ud67rhbwl
name: uos
license: AGPLv3
description: Tagging system with a JSON API
root_dependencies:
- src: git https://github.com/vrischmann/zig-sqlite branch-master