diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | backend/build.zig | 12 | ||||
| -rw-r--r-- | backend/build.zig.zon | 8 | ||||
| -rw-r--r-- | backend/src/API/WeaponsAPI.zig | 24 | ||||
| -rw-r--r-- | backend/src/Database/Connection.zig | 28 | ||||
| -rw-r--r-- | backend/src/Models/RangedWeapon.zig | 13 | ||||
| -rw-r--r-- | backend/src/main.zig | 11 | ||||
| -rw-r--r-- | backend/src/root.zig | 4 | ||||
| -rw-r--r-- | backend/src/tests.zig | 7 | ||||
| -rw-r--r-- | db/create_script.sql | 14 | ||||
| -rw-r--r-- | db/docker-compose.yml | 17 |
11 files changed, 125 insertions, 15 deletions
@@ -1,2 +1,4 @@ zig-out .zig-cache + +.env diff --git a/backend/build.zig b/backend/build.zig index 87d6348..648b332 100644 --- a/backend/build.zig +++ b/backend/build.zig @@ -96,6 +96,18 @@ pub fn build(b: *std.Build) void { exe.root_module.addImport("httpz", httpz.module("httpz")); + + // postgres driver + + const pg_module = b.dependency("pg", .{}).module("pg"); + + exe.root_module.addImport("pg", pg_module); + + // .env + + const dotenv_module = b.dependency("dotenv", .{}).module("dotenv"); + exe.root_module.addImport("dotenv", dotenv_module); + // This creates a top level step. Top level steps have a name and can be // invoked by name when running `zig build` (e.g. `zig build run`). // This will evaluate the `run` step rather than the default step. diff --git a/backend/build.zig.zon b/backend/build.zig.zon index 134b3db..911bb3d 100644 --- a/backend/build.zig.zon +++ b/backend/build.zig.zon @@ -36,6 +36,14 @@ .url = "git+https://github.com/karlseguin/http.zig?ref=master#1a4d53b95bc4ac6c84cbc081727428de40c8c635", .hash = "httpz-0.0.0-PNVzrNVOBwDlxyffzwONpI9j9dYqKWXxopU1ZCLt4C09", }, + .pg = .{ + .url = "git+https://github.com/karlseguin/pg.zig?ref=master#e58b318b7867ef065b3135983f829219c5eef891", + .hash = "pg-0.0.0-Wp_7gXFoBgD0fQ72WICKa-bxLga03AXXQ3BbIsjjohQ3", + }, + .dotenv = .{ + .url = "git+https://github.com/zigster64/dotenv.zig?ref=main#7d50f9fe0ce223d94d180d5a5a49fe0df5bc3743", + .hash = "dotenv-0.1.0-Q9TxeuEMAADw6cHl9uKbjwunS0PlYYc1yw9Ol82TwAAm", + }, }, .paths = .{ "build.zig", diff --git a/backend/src/API/WeaponsAPI.zig b/backend/src/API/WeaponsAPI.zig new file mode 100644 index 0000000..65e3fe8 --- /dev/null +++ b/backend/src/API/WeaponsAPI.zig @@ -0,0 +1,24 @@ +const httpz = @import("httpz"); +const model = @import("../Models/RangedWeapon.zig"); + +pub fn RegisterEndpoints(router: *httpz.Router(void, *const fn (*httpz.request.Request, *httpz.response.Response) anyerror!void)) void { + router.get("/weapons", testEndpoint, .{}); +} + +fn testEndpoint(_: *httpz.Request, res: *httpz.Response) !void { + const testType: model.RangedWeaponType = .{ + .Name = "BudgetArms C-13", + .WeaponType = "P", + .Accuracy = -1, + .Concealability = "P", + .Avaliability = "E", + .Damage = "1D6", + .Ammunition = "5mm", + .NumberOfShots = 8, + .RateOfFire = 2, + .Reliability = "ST" + }; + + res.status = 200; + try res.json(testType, .{}); +} diff --git a/backend/src/Database/Connection.zig b/backend/src/Database/Connection.zig new file mode 100644 index 0000000..638d92b --- /dev/null +++ b/backend/src/Database/Connection.zig @@ -0,0 +1,28 @@ +const std = @import("std"); +const pg = @import("pg"); +const dotenv = @import("dotenv"); + +var pool: *pg.Pool = undefined; + +pub fn Connect(alloc: std.mem.Allocator) !void { + var env = try dotenv.init(alloc, ".env"); + defer env.deinit(); + + pool = try pg.Pool.init(alloc, .{ + .size = 5, + .connect = .{ + .port = 5432, + .host = "localhost" + }, + .auth = .{ + .database = "cyber2020", + .username = env.get("PG_USERNAME") orelse unreachable, + .password = env.get("PG_PASSWORD") orelse unreachable, + .timeout = 10_000 + } + }); +} + +pub fn Disconnect() void { + pool.deinit(); +} diff --git a/backend/src/Models/RangedWeapon.zig b/backend/src/Models/RangedWeapon.zig index 7ec1f01..bfc40b6 100644 --- a/backend/src/Models/RangedWeapon.zig +++ b/backend/src/Models/RangedWeapon.zig @@ -1,6 +1,8 @@ const std = @import("std"); pub const RangedWeaponType = struct { + Name: []const u8, + WeaponType: []const u8, Accuracy: i8, Concealability: []const u8, @@ -29,8 +31,11 @@ pub const RangedWeaponType = struct { } }; -test "CompactNotation" { - var testType: RangedWeaponType = .{ +// ==================== tests ==================== + +fn getTestType() RangedWeaponType { + return .{ + .Name = "any", .WeaponType = "P", .Accuracy = -1, .Concealability = "P", @@ -41,6 +46,10 @@ test "CompactNotation" { .RateOfFire = 2, .Reliability = "ST" }; +} + +test "CompactNotation" { + var testType = getTestType(); try std.testing.expectEqualStrings( "P/-1/P/E/1D6(5mm)/8/2/ST", diff --git a/backend/src/main.zig b/backend/src/main.zig index d2f9a1f..951a86c 100644 --- a/backend/src/main.zig +++ b/backend/src/main.zig @@ -1,7 +1,7 @@ const std = @import("std"); const backend = @import("backend"); const httpz = @import("httpz"); -const tests = @import("tests.zig"); +const db = @import("Database/Connection.zig"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; @@ -16,9 +16,16 @@ pub fn main() !void { server.deinit(); } + var router = try server.router(.{}); router.get("/", index, .{}); + @import("API/WeaponsAPI.zig").RegisterEndpoints(router); + + // PSQL connection + try db.Connect(allocator); + defer db.Disconnect(); + try server.listen(); } @@ -28,5 +35,5 @@ fn index(_: *httpz.Request, res: *httpz.Response) !void { } test "TestRunner" { - std.testing.refAllDecls(@This()); + _ = @import("Models/RangedWeapon.zig"); } diff --git a/backend/src/root.zig b/backend/src/root.zig index 94c7cd0..f8903fa 100644 --- a/backend/src/root.zig +++ b/backend/src/root.zig @@ -17,7 +17,3 @@ pub fn bufferedPrint() !void { pub fn add(a: i32, b: i32) i32 { return a + b; } - -test "basic add functionality" { - try std.testing.expect(add(3, 7) == 10); -} diff --git a/backend/src/tests.zig b/backend/src/tests.zig deleted file mode 100644 index 3c09b99..0000000 --- a/backend/src/tests.zig +++ /dev/null @@ -1,7 +0,0 @@ -const std = @import("std"); -const ranged = @import("Models/RangedWeapon.zig"); - - -test "Runner" { - std.testing.refAllDecls(@This()); -} diff --git a/db/create_script.sql b/db/create_script.sql new file mode 100644 index 0000000..9ee372e --- /dev/null +++ b/db/create_script.sql @@ -0,0 +1,14 @@ +CREATE TABLE weapons ( + id SERIAL PRIMARY KEY, + weapon_type VARCHAR(255) NOT NULL, + accuracy SMALLINT CHECK (accuracy BETWEEN -128 AND 127), + concealability VARCHAR(255) NOT NULL, + availability VARCHAR(255) NOT NULL, + damage VARCHAR(255) NOT NULL, + ammunition VARCHAR(255) NOT NULL, + number_of_shots SMALLINT CHECK (number_of_shots BETWEEN 0 AND 255), + rate_of_fire SMALLINT CHECK (rate_of_fire BETWEEN 0 AND 255), + reliability VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/db/docker-compose.yml b/db/docker-compose.yml new file mode 100644 index 0000000..6f2a675 --- /dev/null +++ b/db/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + postgres: + image: postgres:latest + container_name: cyber2020_pg + environment: + POSTGRES_USER: dev + POSTGRES_PASSWORD: dev + POSTGRES_DB: cyber2020 + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql + +volumes: + postgres_data: |
