Lots of things, idk o_0
This commit is contained in:
parent
4f59f87fbf
commit
3e85bcde6c
|
@ -12,7 +12,6 @@ pub fn build(b: *std.build.Builder) void {
|
||||||
const mode = b.standardReleaseOptions();
|
const mode = b.standardReleaseOptions();
|
||||||
|
|
||||||
const exe = b.addExecutable("mgtzm", "src/main.zig");
|
const exe = b.addExecutable("mgtzm", "src/main.zig");
|
||||||
exe.use_stage1 = true; // for sqlite
|
|
||||||
|
|
||||||
// Add dependencies
|
// Add dependencies
|
||||||
exe.linkSystemLibrary("json-c");
|
exe.linkSystemLibrary("json-c");
|
||||||
|
|
|
@ -215,7 +215,7 @@ pub fn fromJson(jobj: json.Obj, allocator: std.mem.Allocator) !Self {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tagsFromJson(jobj: *json.Obj, allocator: std.mem.Allocator) ![]Tag {
|
pub fn tagsFromJson(jobj: *const json.Obj, allocator: std.mem.Allocator) ![]Tag {
|
||||||
// Reserve space for slice of tags
|
// Reserve space for slice of tags
|
||||||
const len = @intCast(usize, jobj.arrayLen());
|
const len = @intCast(usize, jobj.arrayLen());
|
||||||
var tags = try allocator.alloc(Tag, len);
|
var tags = try allocator.alloc(Tag, len);
|
||||||
|
|
30
src/json.zig
30
src/json.zig
|
@ -4,7 +4,7 @@ pub const c = @cImport({
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const Type = enum(c.json_type) {
|
const Type = enum(c.json_type) {
|
||||||
@"null" = c.json_type_null,
|
null = c.json_type_null,
|
||||||
boolean = c.json_type_boolean,
|
boolean = c.json_type_boolean,
|
||||||
double = c.json_type_double,
|
double = c.json_type_double,
|
||||||
int = c.json_type_int,
|
int = c.json_type_int,
|
||||||
|
@ -36,8 +36,14 @@ pub const Obj = struct {
|
||||||
pub fn newInt64(i: i64) Obj {
|
pub fn newInt64(i: i64) Obj {
|
||||||
return Obj{ .obj = c.json_object_new_int64(i).? };
|
return Obj{ .obj = c.json_object_new_int64(i).? };
|
||||||
}
|
}
|
||||||
pub fn newFromString(s: [*c]const u8) Obj {
|
pub fn newFromString(s: [*c]const u8) !Obj {
|
||||||
return Obj{ .obj = c.json_tokener_parse(s).? };
|
const FromStringError = error{
|
||||||
|
MalformedString,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Obj{
|
||||||
|
.obj = c.json_tokener_parse(s) orelse return FromStringError.MalformedString,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Obj) void {
|
pub fn deinit(self: *Obj) void {
|
||||||
|
@ -58,7 +64,7 @@ pub const Obj = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not *const Obj because the json_object retains ownership of the string
|
// Not *const Obj because the json_object retains ownership of the string
|
||||||
pub fn toString(self: *Obj) []const u8 {
|
pub fn toString(self: *const Obj) []const u8 {
|
||||||
// TODO: Allow passing of flags as an enum like the SDL2 binding
|
// TODO: Allow passing of flags as an enum like the SDL2 binding
|
||||||
return std.mem.sliceTo(c.json_object_to_json_string(self.obj), 0);
|
return std.mem.sliceTo(c.json_object_to_json_string(self.obj), 0);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +74,7 @@ pub const Obj = struct {
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
// Not *const Obj because the json_object retains ownership of the string
|
// Not *const Obj because the json_object retains ownership of the string
|
||||||
pub fn getString(self: *Obj) []const u8 {
|
pub fn getString(self: *const Obj) []const u8 {
|
||||||
// TODO: Check type to not allow other types
|
// TODO: Check type to not allow other types
|
||||||
return std.mem.sliceTo(c.json_object_get_string(self.obj), 0);
|
return std.mem.sliceTo(c.json_object_get_string(self.obj), 0);
|
||||||
}
|
}
|
||||||
|
@ -104,7 +110,7 @@ pub const Obj = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn objectAdd(self: *Obj, key: [*c]const u8, value: ?*Obj) void {
|
pub fn objectAdd(self: *Obj, key: [*c]const u8, value: ?*const Obj) void {
|
||||||
// TODO: Check type and error return
|
// TODO: Check type and error return
|
||||||
|
|
||||||
// We need the json-c object or null, not the zig object
|
// We need the json-c object or null, not the zig object
|
||||||
|
@ -113,6 +119,10 @@ pub const Obj = struct {
|
||||||
_ = c.json_object_object_add(self.obj, key, o);
|
_ = c.json_object_object_add(self.obj, key, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn objectAddString(self: *Obj, key: [*c]const u8, value: [*c]const u8) void {
|
||||||
|
_ = c.json_object_object_add(self.obj, key, newString(value).obj);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn objectLen(self: *const Obj) c_int {
|
pub fn objectLen(self: *const Obj) c_int {
|
||||||
return c.json_object_object_length(self.obj);
|
return c.json_object_object_length(self.obj);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +171,7 @@ pub const Obj = struct {
|
||||||
// ** Array functions **
|
// ** Array functions **
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
pub fn arrayAdd(self: *Obj, value: ?*Obj) void {
|
pub fn arrayAdd(self: *Obj, value: ?*const Obj) void {
|
||||||
// TODO: Check type and error return
|
// TODO: Check type and error return
|
||||||
|
|
||||||
// We need the json-c object or null, not the zig object
|
// We need the json-c object or null, not the zig object
|
||||||
|
@ -173,7 +183,7 @@ pub const Obj = struct {
|
||||||
return c.json_object_array_length(self.obj);
|
return c.json_object_array_length(self.obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arrayGet(self: *Obj, idx: usize) ?Obj {
|
pub fn arrayGet(self: *const Obj, idx: usize) ?Obj {
|
||||||
// Sould the .? be there?
|
// Sould the .? be there?
|
||||||
if (c.json_object_array_get_idx(self.obj, idx)) |obj| {
|
if (c.json_object_array_get_idx(self.obj, idx)) |obj| {
|
||||||
return Obj{ .obj = c.json_object_get(obj).? };
|
return Obj{ .obj = c.json_object_get(obj).? };
|
||||||
|
@ -182,12 +192,12 @@ pub const Obj = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arrayGetIterator (self: *Obj) ArrayIterator {
|
pub fn arrayGetIterator(self: *const Obj) ArrayIterator {
|
||||||
return ArrayIterator{ .obj = self, .idx = 0 };
|
return ArrayIterator{ .obj = self, .idx = 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ArrayIterator = struct {
|
pub const ArrayIterator = struct {
|
||||||
obj: *Obj,
|
obj: *const Obj,
|
||||||
idx: usize = 0,
|
idx: usize = 0,
|
||||||
|
|
||||||
pub fn next(self: *ArrayIterator) ?Obj {
|
pub fn next(self: *ArrayIterator) ?Obj {
|
||||||
|
|
104
src/main.zig
104
src/main.zig
|
@ -5,66 +5,64 @@ 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");
|
||||||
|
const util = @import("util.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
|
|
||||||
var db = Db.open("test.tkh", true, "");
|
var db = Db.open("test.tkh", true, "");
|
||||||
|
const sock_path = "/tmp/mgtzm.sock";
|
||||||
|
|
||||||
// ---------------------- ADD ---------------------------
|
// Remove the socket file if it exists
|
||||||
|
std.fs.deleteFileAbsolute(sock_path) catch |err| {
|
||||||
|
switch (err) {
|
||||||
|
// Do not error out if the file doesn't exist
|
||||||
|
error.FileNotFound => {},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const jsonText: [:0]const u8 =
|
var server = std.net.StreamServer.init(.{});
|
||||||
\\{ "add" : [
|
defer server.deinit();
|
||||||
\\ [
|
const addr = try std.net.Address.initUnix(sock_path);
|
||||||
\\ "task:uned:led",
|
|
||||||
\\ "fur:dusk",
|
|
||||||
\\ "made_with:krita",
|
|
||||||
\\ "date:2022:10:01",
|
|
||||||
\\ "alunya"
|
|
||||||
\\ ],[
|
|
||||||
\\ "fur:lara",
|
|
||||||
\\ "made_with:krita",
|
|
||||||
\\ "date:2022:04:08",
|
|
||||||
\\ "cell-shading"
|
|
||||||
\\ ],[
|
|
||||||
\\ "made_with:ballpoint_pen",
|
|
||||||
\\ "date:2022:11:04",
|
|
||||||
\\ "practice",
|
|
||||||
\\ "pose_practice"
|
|
||||||
\\ ],[
|
|
||||||
\\ "fur:lidiarock1",
|
|
||||||
\\ "made_with:krita",
|
|
||||||
\\ "date:2022:10:15",
|
|
||||||
\\ "niko_(oneshot)"
|
|
||||||
\\ ]
|
|
||||||
\\] }
|
|
||||||
;
|
|
||||||
|
|
||||||
var jobj = json.Obj.newFromString(jsonText);
|
try server.listen(addr);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
// ----------------
|
||||||
|
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
|
const connection = try server.accept();
|
||||||
|
defer connection.stream.close();
|
||||||
|
|
||||||
|
// Receive and process message
|
||||||
|
// ----------------
|
||||||
|
|
||||||
|
const read = connection.stream.reader();
|
||||||
|
|
||||||
|
var msg = util.readUntilDelimiterAllocZ(read, allocator, 0, 1024) catch |err| {
|
||||||
|
std.debug.print("Failed to read from connection: {any}\n", .{err});
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
defer allocator.free(msg);
|
||||||
|
|
||||||
|
var jobj = json.Obj.newFromString(msg) catch {
|
||||||
|
var errorObj = json.Obj.newObject();
|
||||||
|
errorObj.objectAddString("error", "Invalid JSON request.");
|
||||||
|
|
||||||
|
_ = connection.stream.write(errorObj.toString()) catch {};
|
||||||
|
continue;
|
||||||
|
};
|
||||||
defer jobj.deinit();
|
defer jobj.deinit();
|
||||||
|
|
||||||
try request.process(&jobj, &db);
|
const answer = try request.process(&jobj, &db, allocator);
|
||||||
|
defer allocator.free(answer);
|
||||||
|
|
||||||
std.debug.print("\n\n", .{});
|
// Reply
|
||||||
|
// ----------------
|
||||||
// -------------------- DELETE --------------------------
|
_ = try connection.stream.write(answer);
|
||||||
|
}
|
||||||
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" : "" }
|
|
||||||
;
|
|
||||||
|
|
||||||
var jquery = json.Obj.newFromString(jsonQuery);
|
|
||||||
defer jquery.deinit();
|
|
||||||
|
|
||||||
try request.process(&jquery, &db);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,34 +6,38 @@ const Tag = @import("Tag.zig");
|
||||||
const json = @import("json.zig");
|
const json = @import("json.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
pub fn process(jobj: *json.Obj, db: *Db) !void {
|
pub fn process(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) ![]const u8 {
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
||||||
defer arena.deinit();
|
|
||||||
const allocator = arena.allocator();
|
|
||||||
|
|
||||||
var jret = json.Obj.newObject();
|
var jret = json.Obj.newObject();
|
||||||
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) |*jaction| {
|
// TODO: Change to { "type" : "<action>", "data" : <data> }
|
||||||
|
// TODO: Automatize this, give a list of actions and autobuild the checks in comptime
|
||||||
|
if (jobj.objectGet("add")) |*jaction| {
|
||||||
var ret = try add(jaction, db, allocator);
|
var ret = try add(jaction, db, allocator);
|
||||||
jret.objectAdd("added", &ret);
|
// TODO: Maybe change all of these to "affected"?
|
||||||
}
|
jret.objectAddString("type", "added");
|
||||||
|
jret.objectAdd("data", &ret);
|
||||||
|
} else |_| {}
|
||||||
|
|
||||||
if (jobj.objectGet("query") catch null) |*jaction| {
|
if (jobj.objectGet("query")) |*jaction| {
|
||||||
var ret = try query(jaction, db, allocator);
|
var ret = try query(jaction, db, allocator);
|
||||||
jret.objectAdd("queried", &ret);
|
jret.objectAddString("type", "queried");
|
||||||
}
|
jret.objectAdd("data", &ret);
|
||||||
|
} else |_| {}
|
||||||
|
|
||||||
if (jobj.objectGet("delete") catch null) |*jaction| {
|
if (jobj.objectGet("delete")) |*jaction| {
|
||||||
var ret = try delete(jaction, db, allocator);
|
var ret = try delete(jaction, db, allocator);
|
||||||
jret.objectAdd("deleted", &ret);
|
jret.objectAddString("type", "deleted");
|
||||||
|
jret.objectAdd("data", &ret);
|
||||||
|
} else |_| {}
|
||||||
|
|
||||||
|
const ret_str = std.mem.sliceTo(jret.toString(), 0);
|
||||||
|
|
||||||
|
return allocator.dupe(u8, ret_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
std.debug.print("{s}\n", .{jret.toString()});
|
pub fn add(jobj: *const json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
|
||||||
// TODO: Maybe return error when no items in the array?
|
// TODO: Maybe return error when no items in the array?
|
||||||
|
|
||||||
// Freed by the caller
|
// Freed by the caller
|
||||||
|
@ -57,7 +61,7 @@ pub fn add(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||||
return jret;
|
return jret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn query(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
pub fn query(jobj: *const json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||||
// TODO: Have into account limits so it is scalable
|
// TODO: Have into account limits so it is scalable
|
||||||
// TODO: Do not fetch EVERY id at once, iterate where possible
|
// TODO: Do not fetch EVERY id at once, iterate where possible
|
||||||
const query_str = jobj.getString();
|
const query_str = jobj.getString();
|
||||||
|
@ -100,7 +104,7 @@ pub fn query(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||||
return jret;
|
return jret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(jobj: *json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
pub fn delete(jobj: *const json.Obj, db: *Db, allocator: std.mem.Allocator) !json.Obj {
|
||||||
var jret = json.Obj.newArray();
|
var jret = json.Obj.newArray();
|
||||||
|
|
||||||
// Go over each tag
|
// Go over each tag
|
||||||
|
|
15
src/util.zig
15
src/util.zig
|
@ -1,6 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
|
||||||
pub const IntersectionIterator = struct {
|
pub const IntersectionIterator = struct {
|
||||||
ref: std.mem.TokenIterator(u8),
|
ref: std.mem.TokenIterator(u8),
|
||||||
rest: []const []const u8,
|
rest: []const []const u8,
|
||||||
|
@ -40,3 +39,17 @@ pub fn intersection(slices: []const []const u8) IntersectionIterator {
|
||||||
.rest = slices[1..],
|
.rest = slices[1..],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn readUntilDelimiterAllocZ(
|
||||||
|
reader: anytype, // TODO: Fix this and set the correct type, I got no clue rn
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
delimiter: u8,
|
||||||
|
max_size: usize,
|
||||||
|
) ![:0]u8 {
|
||||||
|
var array_list = std.ArrayList(u8).init(allocator);
|
||||||
|
defer array_list.deinit();
|
||||||
|
|
||||||
|
try reader.readUntilDelimiterArrayList(&array_list, delimiter, max_size);
|
||||||
|
|
||||||
|
return array_list.toOwnedSliceSentinel(0);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue