Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
8dede5fad6 | |||
db6b019b5d | |||
20360fc412 | |||
f93af6c717 | |||
c6db34694a | |||
1f6125d2e1 |
12 changed files with 79 additions and 26 deletions
24
.forgejo/workflows/docs.yaml
Normal file
24
.forgejo/workflows/docs.yaml
Normal file
|
@ -0,0 +1,24 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
jobs:
|
||||
build_docs:
|
||||
runs-on: docker
|
||||
container:
|
||||
image: docker.zeptotech.net/zeptotech/zig-yarn:1.1.0
|
||||
credentials:
|
||||
username: ${{ vars.DOCKER_REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: mkdir -p artifact/api
|
||||
- run: (cd docs && corepack enable && yarn install)
|
||||
- run: (cd docs && yarn docs:build)
|
||||
- run: mv docs/.vitepress/dist/* artifact
|
||||
- run: /zig/zig build docs
|
||||
- run: mv zig-out/docs/* artifact/api
|
||||
- uses: https://code.forgejo.org/forgejo/upload-artifact@v4
|
||||
with:
|
||||
name: docs.zip
|
||||
path: artifact
|
|
@ -28,7 +28,7 @@ _ZRM_ provides a simple interface to relational databases in Zig. Define your re
|
|||
|
||||
## Versions
|
||||
|
||||
ZRM 0.3.0 is made and tested with zig 0.13.0.
|
||||
ZRM 0.3.1 is made and tested with zig 0.13.0.
|
||||
|
||||
## Work in progress
|
||||
|
||||
|
@ -41,7 +41,7 @@ ZRM aims to handle a lot for you, but it takes time to make. Have a look to [the
|
|||
In your project directory:
|
||||
|
||||
```shell
|
||||
$ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.0.tar.gz
|
||||
$ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.1.tar.gz
|
||||
```
|
||||
|
||||
In `build.zig`:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.{
|
||||
.name = "zrm",
|
||||
.version = "0.3.0",
|
||||
.version = "0.3.1",
|
||||
|
||||
.minimum_zig_version = "0.13.0",
|
||||
|
||||
|
|
|
@ -51,7 +51,19 @@ defer session.deinit();
|
|||
|
||||
Using sessions, you can start transactions and use savepoints.
|
||||
|
||||
::: warning
|
||||
You probably want to rollback all active transactions in `defer`, so that none remain active after leaving the active branch.
|
||||
:::
|
||||
|
||||
```zig
|
||||
// Start a new session.
|
||||
var session = try zrm.Session.init(database);
|
||||
defer {
|
||||
// Rollback all active transactions that remain active.
|
||||
session.rollbackAll();
|
||||
session.deinit();
|
||||
};
|
||||
|
||||
try session.beginTransaction();
|
||||
|
||||
// Do something.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
You can easily install ZRM using the `zig fetch` command:
|
||||
|
||||
```shell
|
||||
$ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.0.tar.gz
|
||||
$ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.1.tar.gz
|
||||
```
|
||||
|
||||
::: info
|
||||
|
@ -18,8 +18,8 @@ This should add something like the following in `build.zig.zon` dependencies:
|
|||
.dependencies = .{
|
||||
// ...
|
||||
.zrm = .{
|
||||
.url = "https://code.zeptotech.net/zedd/zrm/archive/v0.3.0.tar.gz",
|
||||
.hash = "12200fe147879d72381633e6f44d76db2c8a603cda1969b4e474c15c31052dbb24b7",
|
||||
.url = "https://code.zeptotech.net/zedd/zrm/archive/v0.3.1.tar.gz",
|
||||
.hash = "12200fe...",
|
||||
},
|
||||
// ...
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const std = @import("std");
|
||||
const _sql = @import("sql.zig");
|
||||
const errors = @import("errors.zig");
|
||||
const ZrmError = @import("errors.zig").ZrmError;
|
||||
|
||||
const Static = @This();
|
||||
|
||||
|
@ -78,7 +78,7 @@ pub fn in(comptime ValueType: type, allocator: std.mem.Allocator, _column: []con
|
|||
fn conditionsCombiner(comptime keyword: []const u8, allocator: std.mem.Allocator, subconditions: []const _sql.RawQuery) !_sql.RawQuery {
|
||||
if (subconditions.len == 0) {
|
||||
// At least one condition is required.
|
||||
return errors.ZrmError.AtLeastOneConditionRequired;
|
||||
return ZrmError.AtLeastOneConditionRequired;
|
||||
}
|
||||
|
||||
// Full keyword constant.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const std = @import("std");
|
||||
const pg = @import("pg");
|
||||
const zollections = @import("zollections");
|
||||
const errors = @import("errors.zig");
|
||||
const ZrmError = @import("errors.zig").ZrmError;
|
||||
const database = @import("database.zig");
|
||||
const postgresql = @import("postgresql.zig");
|
||||
const _sql = @import("sql.zig");
|
||||
|
@ -196,14 +196,14 @@ pub fn RepositoryInsert(comptime Model: type, comptime TableShape: type, comptim
|
|||
}
|
||||
|
||||
/// Set selected columns for RETURNING clause.
|
||||
pub fn returningColumns(self: *Self, _select: []const []const u8) void {
|
||||
pub fn returningColumns(self: *Self, _select: []const []const u8) !void {
|
||||
if (_select.len == 0) {
|
||||
return errors.AtLeastOneSelectionRequired;
|
||||
return ZrmError.AtLeastOneSelectionRequired;
|
||||
}
|
||||
|
||||
self.returning(.{
|
||||
// Join selected columns.
|
||||
.sql = std.mem.join(self.arena.allocator(), ", ", _select),
|
||||
.sql = try std.mem.join(self.arena.allocator(), ", ", _select),
|
||||
.params = &[_]_sql.RawQueryParameter{}, // No parameters.
|
||||
});
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ pub fn RepositoryInsert(comptime Model: type, comptime TableShape: type, comptim
|
|||
pub fn buildSql(self: *Self) !void {
|
||||
if (self.insertConfig.values.len == 0) {
|
||||
// At least one value is required to insert.
|
||||
return errors.ZrmError.AtLeastOneValueRequired;
|
||||
return ZrmError.AtLeastOneValueRequired;
|
||||
}
|
||||
|
||||
// Compute VALUES parameters count.
|
||||
|
|
|
@ -2,7 +2,7 @@ const std = @import("std");
|
|||
const pg = @import("pg");
|
||||
const zollections = @import("zollections");
|
||||
const global = @import("global.zig");
|
||||
const errors = @import("errors.zig");
|
||||
const ZrmError = @import("errors.zig").ZrmError;
|
||||
const database = @import("database.zig");
|
||||
const _sql = @import("sql.zig");
|
||||
const _relationships = @import("relationships.zig");
|
||||
|
@ -51,7 +51,7 @@ pub fn handleRawPostgresqlError(err: anyerror, connection: *pg.Conn) anyerror {
|
|||
}
|
||||
|
||||
// Return that an error happened in query execution.
|
||||
return errors.ZrmError.QueryFailed;
|
||||
return ZrmError.QueryFailed;
|
||||
} else {
|
||||
// Not an SQL error, just return it.
|
||||
return err;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const std = @import("std");
|
||||
const pg = @import("pg");
|
||||
const zollections = @import("zollections");
|
||||
const errors = @import("errors.zig");
|
||||
const ZrmError = @import("errors.zig").ZrmError;
|
||||
const database = @import("database.zig");
|
||||
const postgresql = @import("postgresql.zig");
|
||||
const _sql = @import("sql.zig");
|
||||
|
@ -105,7 +105,7 @@ pub fn RepositoryQuery(comptime Model: type, comptime TableShape: type, comptime
|
|||
/// Set selected columns for SELECT clause.
|
||||
pub fn selectColumns(self: *Self, _select: []const []const u8) !void {
|
||||
if (_select.len == 0) {
|
||||
return errors.AtLeastOneSelectionRequired;
|
||||
return ZrmError.AtLeastOneSelectionRequired;
|
||||
}
|
||||
|
||||
self.select(.{
|
||||
|
|
|
@ -12,6 +12,9 @@ pub const Session = struct {
|
|||
/// The active connection for the session.
|
||||
connection: *pg.Conn,
|
||||
|
||||
/// The count of active transactions for the session.
|
||||
activeTransactions: usize = 0,
|
||||
|
||||
/// Execute a comptime-known SQL command for the current session.
|
||||
fn exec(self: Self, comptime sql: []const u8) !void {
|
||||
_ = self.connection.exec(sql, .{}) catch |err| {
|
||||
|
@ -29,11 +32,25 @@ pub const Session = struct {
|
|||
try self.exec("ROLLBACK;");
|
||||
}
|
||||
|
||||
/// Rollback all active transactions.
|
||||
pub fn rollbackAll(self: Self) !void {
|
||||
for (0..self.activeTransactions) |_| {
|
||||
self.rollbackTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/// Commit the current transaction.
|
||||
pub fn commitTransaction(self: Self) !void {
|
||||
try self.exec("COMMIT;");
|
||||
}
|
||||
|
||||
/// Commit all active transactions.
|
||||
pub fn commitAll(self: Self) !void {
|
||||
for (0..self.activeTransactions) |_| {
|
||||
self.commitTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new savepoint with the given name.
|
||||
pub fn savepoint(self: Self, comptime _savepoint: []const u8) !void {
|
||||
try self.exec("SAVEPOINT " ++ _savepoint ++ ";");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const std = @import("std");
|
||||
const errors = @import("errors.zig");
|
||||
const ZrmError = @import("errors.zig").ZrmError;
|
||||
|
||||
/// A structure with SQL and its parameters.
|
||||
pub const RawQuery = struct {
|
||||
|
@ -120,7 +120,7 @@ pub const RawQueryParameter = union(enum) {
|
|||
null: void,
|
||||
|
||||
/// Convert any value to a query parameter.
|
||||
pub fn fromValue(value: anytype) errors.ZrmError!RawQueryParameter {
|
||||
pub fn fromValue(value: anytype) ZrmError!RawQueryParameter {
|
||||
// Get given value type.
|
||||
const valueType = @typeInfo(@TypeOf(value));
|
||||
|
||||
|
@ -138,7 +138,7 @@ pub const RawQueryParameter = union(enum) {
|
|||
if (pointer.child == u8) {
|
||||
return .{ .string = value };
|
||||
} else {
|
||||
return errors.ZrmError.UnsupportedTableType;
|
||||
return ZrmError.UnsupportedTableType;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -154,7 +154,7 @@ pub const RawQueryParameter = union(enum) {
|
|||
return .{ .null = true };
|
||||
}
|
||||
},
|
||||
else => return errors.ZrmError.UnsupportedTableType
|
||||
else => return ZrmError.UnsupportedTableType
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const std = @import("std");
|
||||
const pg = @import("pg");
|
||||
const zollections = @import("zollections");
|
||||
const errors = @import("errors.zig");
|
||||
const ZrmError = @import("errors.zig").ZrmError;
|
||||
const database = @import("database.zig");
|
||||
const postgresql = @import("postgresql.zig");
|
||||
const _sql = @import("sql.zig");
|
||||
|
@ -153,14 +153,14 @@ pub fn RepositoryUpdate(comptime Model: type, comptime TableShape: type, comptim
|
|||
}
|
||||
|
||||
/// Set selected columns for RETURNING clause.
|
||||
pub fn returningColumns(self: *Self, _select: []const []const u8) void {
|
||||
pub fn returningColumns(self: *Self, _select: []const []const u8) !void {
|
||||
if (_select.len == 0) {
|
||||
return errors.AtLeastOneSelectionRequired;
|
||||
return ZrmError.AtLeastOneSelectionRequired;
|
||||
}
|
||||
|
||||
self.returning(.{
|
||||
// Join selected columns.
|
||||
.sql = std.mem.join(self.arena.allocator(), ", ", _select),
|
||||
.sql = try std.mem.join(self.arena.allocator(), ", ", _select),
|
||||
.params = &[_]_sql.RawQueryParameter{}, // No parameters.
|
||||
});
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ pub fn RepositoryUpdate(comptime Model: type, comptime TableShape: type, comptim
|
|||
pub fn buildSql(self: *Self) !void {
|
||||
if (self.updateConfig.value) |_| {} else {
|
||||
// Updated values must be set.
|
||||
return errors.ZrmError.UpdatedValuesRequired;
|
||||
return ZrmError.UpdatedValuesRequired;
|
||||
}
|
||||
|
||||
// Start parameter counter at 1.
|
||||
|
|
Loading…
Add table
Reference in a new issue