diff options
Diffstat (limited to 'backend')
| -rw-r--r-- | backend/src/API/WeaponsAPI.zig | 45 | ||||
| -rw-r--r-- | backend/src/Database/RangedWeaponsAccessLayer.zig | 26 | ||||
| -rw-r--r-- | backend/src/Models/Description.zig | 36 |
3 files changed, 107 insertions, 0 deletions
diff --git a/backend/src/API/WeaponsAPI.zig b/backend/src/API/WeaponsAPI.zig index 66871df..7c8d72a 100644 --- a/backend/src/API/WeaponsAPI.zig +++ b/backend/src/API/WeaponsAPI.zig @@ -1,6 +1,7 @@ const std = @import("std"); const httpz = @import("httpz"); const model = @import("../Models/RangedWeapon.zig"); +const descModel = @import("../Models/Description.zig"); const db = @import("../Database/Connection.zig"); const errDesc = @import("ErrorDescription.zig"); const Handler = @import("../Handler.zig"); @@ -8,6 +9,8 @@ const Handler = @import("../Handler.zig"); pub fn RegisterEndpoints(router: *httpz.Router(*Handler.Handler,*const fn (*Handler.RequestData, *httpz.request.Request, *httpz.response.Response) anyerror!void)) void { router.get("/weapons/ranged", getAllRangedWeapons, .{}); router.post("/weapons/ranged", newRangedWeapon, .{}); + router.get("/weapons/ranged/:id/description", getRangedWeaponDescription, .{}); + router.post("/weapons/ranged/:id/description", setRangedWeaponDescription, .{}); router.get("/weapons/ranged/:id", getRangedWeaponById, .{}); router.put("/weapons/ranged/:id", updateRangedWeapon, .{}); router.delete("/weapons/ranged/:id", deleteRangedWeapon, .{}); @@ -90,3 +93,45 @@ fn deleteRangedWeapon(_: *Handler.RequestData, req: *httpz.Request, res: *httpz. try db.RangedWeapons.Delete(id); } + +fn getRangedWeaponDescription(_: *Handler.RequestData, req: *httpz.Request, res: *httpz.Response) !void { + const id = req.param("id") orelse { + res.setStatus(.bad_request); + return; + }; + + const query = try req.query(); + const lang = query.get("lang") orelse "en"; + const desc = db.RangedWeapons.GetDescription(req.arena, id, lang) catch |err| { + if (err == db.ResultErrors.NotFound) { + // The description does not exist + try res.json(descModel.Description { + .Id = id, + .Language = lang, + .Contents = "" + }, .{}); + return; + } + return err; + }; + + try res.json(desc, .{}); +} + +fn setRangedWeaponDescription(_: *Handler.RequestData, req: *httpz.Request, res: *httpz.Response) !void { + const id = req.param("id") orelse { + res.setStatus(.bad_request); + return; + }; + + const body = try req.json(descModel.RequestBody) orelse { + res.setStatus(.bad_request); + return; + }; + + try db.RangedWeapons.SetDescription(.{ + .Id = id, + .Language = body.Language, + .Contents = body.Contents + }); +} diff --git a/backend/src/Database/RangedWeaponsAccessLayer.zig b/backend/src/Database/RangedWeaponsAccessLayer.zig index 34c71ea..6857581 100644 --- a/backend/src/Database/RangedWeaponsAccessLayer.zig +++ b/backend/src/Database/RangedWeaponsAccessLayer.zig @@ -5,6 +5,7 @@ const conn = @import("Connection.zig"); const std = @import("std"); const pg = @import("pg"); const model = @import("../Models/RangedWeapon.zig"); +const descriptionModel = @import("../Models/Description.zig"); pub fn GetAll(alloc: std.mem.Allocator) !std.ArrayList(model.RangedWeaponType) { const query = "SELECT * FROM RangedWeapons ORDER BY weapon_type"; @@ -104,3 +105,28 @@ pub fn Delete(displayName: []const u8) !void { displayName, }); } + +pub fn GetDescription(allocator: std.mem.Allocator, displayName: []const u8, language: []const u8) !descriptionModel.Description { + const query = "SELECT * FROM RangedWeaponsDescriptions WHERE id = $1 AND language = $2"; + var row = try conn.pool.row(query, .{displayName, language}) orelse { + return conn.ResultErrors.NotFound; + }; + const outp = try descriptionModel.Description.MapWithAlloc(allocator, &row.row); + try row.deinit(); + return outp; +} + +pub fn SetDescription(Model: descriptionModel.Description) !void { + const query = + \\ INSERT INTO RangedWeaponsDescriptions (id, language, contents) + \\ VALUES ($1, $2, $3) + \\ ON CONFLICT (id, language) + \\ DO UPDATE SET contents = EXCLUDED.contents + ; + + _ = try conn.pool.exec(query, .{ + Model.Id, + Model.Language, + Model.Contents, + }); +} diff --git a/backend/src/Models/Description.zig b/backend/src/Models/Description.zig new file mode 100644 index 0000000..a3774ab --- /dev/null +++ b/backend/src/Models/Description.zig @@ -0,0 +1,36 @@ +const std = @import("std"); +const pg = @import("pg"); + +// Is suitable for those tables: +// - RangedWeaponsDescriptions +pub const Description = struct { + Id: []const u8, + Language: []const u8, + Contents: []const u8, + + // Parses the db row and returns the result. You are expected to use the + // actual DB schema and use * as a fields selector + pub fn Map(row: *const pg.Row) !Description { + return Description { + .Id = try row.get([]const u8, 0), + .Language = try row.get([]const u8, 1), + .Contents = try row.get([]const u8, 2), + }; + } + + // Parses the db row and returns the result. You are expected to use the + // actual DB schema and use * as a fields selector + pub fn MapWithAlloc(allocator: std.mem.Allocator, row: *const pg.Row) !Description { + return Description { + .Id = try allocator.dupe(u8, try row.get([]const u8, 0)), + .Language = try allocator.dupe(u8, try row.get([]const u8, 1)), + .Contents = try allocator.dupe(u8, try row.get([]const u8, 2)), + }; + } + +}; + +pub const RequestBody = struct { + Language: []const u8, + Contents: []const u8, +}; |
