Compare commits

..

No commits in common. "main" and "v0.3.0" have entirely different histories.
main ... v0.3.0

12 changed files with 26 additions and 79 deletions

View file

@ -1,24 +0,0 @@
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

View file

@ -28,7 +28,7 @@ _ZRM_ provides a simple interface to relational databases in Zig. Define your re
## Versions ## Versions
ZRM 0.3.1 is made and tested with zig 0.13.0. ZRM 0.3.0 is made and tested with zig 0.13.0.
## Work in progress ## 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: In your project directory:
```shell ```shell
$ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.1.tar.gz $ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.0.tar.gz
``` ```
In `build.zig`: In `build.zig`:

View file

@ -1,6 +1,6 @@
.{ .{
.name = "zrm", .name = "zrm",
.version = "0.3.1", .version = "0.3.0",
.minimum_zig_version = "0.13.0", .minimum_zig_version = "0.13.0",

View file

@ -51,19 +51,7 @@ defer session.deinit();
Using sessions, you can start transactions and use savepoints. 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 ```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(); try session.beginTransaction();
// Do something. // Do something.

View file

@ -3,7 +3,7 @@
You can easily install ZRM using the `zig fetch` command: You can easily install ZRM using the `zig fetch` command:
```shell ```shell
$ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.1.tar.gz $ zig fetch --save https://code.zeptotech.net/zedd/zrm/archive/v0.3.0.tar.gz
``` ```
::: info ::: info
@ -18,8 +18,8 @@ This should add something like the following in `build.zig.zon` dependencies:
.dependencies = .{ .dependencies = .{
// ... // ...
.zrm = .{ .zrm = .{
.url = "https://code.zeptotech.net/zedd/zrm/archive/v0.3.1.tar.gz", .url = "https://code.zeptotech.net/zedd/zrm/archive/v0.3.0.tar.gz",
.hash = "12200fe...", .hash = "12200fe147879d72381633e6f44d76db2c8a603cda1969b4e474c15c31052dbb24b7",
}, },
// ... // ...
}, },

View file

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
const _sql = @import("sql.zig"); const _sql = @import("sql.zig");
const ZrmError = @import("errors.zig").ZrmError; const errors = @import("errors.zig");
const Static = @This(); 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 { fn conditionsCombiner(comptime keyword: []const u8, allocator: std.mem.Allocator, subconditions: []const _sql.RawQuery) !_sql.RawQuery {
if (subconditions.len == 0) { if (subconditions.len == 0) {
// At least one condition is required. // At least one condition is required.
return ZrmError.AtLeastOneConditionRequired; return errors.ZrmError.AtLeastOneConditionRequired;
} }
// Full keyword constant. // Full keyword constant.

View file

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const pg = @import("pg"); const pg = @import("pg");
const zollections = @import("zollections"); const zollections = @import("zollections");
const ZrmError = @import("errors.zig").ZrmError; const errors = @import("errors.zig");
const database = @import("database.zig"); const database = @import("database.zig");
const postgresql = @import("postgresql.zig"); const postgresql = @import("postgresql.zig");
const _sql = @import("sql.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. /// 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) { if (_select.len == 0) {
return ZrmError.AtLeastOneSelectionRequired; return errors.AtLeastOneSelectionRequired;
} }
self.returning(.{ self.returning(.{
// Join selected columns. // Join selected columns.
.sql = try std.mem.join(self.arena.allocator(), ", ", _select), .sql = std.mem.join(self.arena.allocator(), ", ", _select),
.params = &[_]_sql.RawQueryParameter{}, // No parameters. .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 { pub fn buildSql(self: *Self) !void {
if (self.insertConfig.values.len == 0) { if (self.insertConfig.values.len == 0) {
// At least one value is required to insert. // At least one value is required to insert.
return ZrmError.AtLeastOneValueRequired; return errors.ZrmError.AtLeastOneValueRequired;
} }
// Compute VALUES parameters count. // Compute VALUES parameters count.

View file

@ -2,7 +2,7 @@ const std = @import("std");
const pg = @import("pg"); const pg = @import("pg");
const zollections = @import("zollections"); const zollections = @import("zollections");
const global = @import("global.zig"); const global = @import("global.zig");
const ZrmError = @import("errors.zig").ZrmError; const errors = @import("errors.zig");
const database = @import("database.zig"); const database = @import("database.zig");
const _sql = @import("sql.zig"); const _sql = @import("sql.zig");
const _relationships = @import("relationships.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 that an error happened in query execution.
return ZrmError.QueryFailed; return errors.ZrmError.QueryFailed;
} else { } else {
// Not an SQL error, just return it. // Not an SQL error, just return it.
return err; return err;

View file

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const pg = @import("pg"); const pg = @import("pg");
const zollections = @import("zollections"); const zollections = @import("zollections");
const ZrmError = @import("errors.zig").ZrmError; const errors = @import("errors.zig");
const database = @import("database.zig"); const database = @import("database.zig");
const postgresql = @import("postgresql.zig"); const postgresql = @import("postgresql.zig");
const _sql = @import("sql.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. /// Set selected columns for SELECT clause.
pub fn selectColumns(self: *Self, _select: []const []const u8) !void { pub fn selectColumns(self: *Self, _select: []const []const u8) !void {
if (_select.len == 0) { if (_select.len == 0) {
return ZrmError.AtLeastOneSelectionRequired; return errors.AtLeastOneSelectionRequired;
} }
self.select(.{ self.select(.{

View file

@ -12,9 +12,6 @@ pub const Session = struct {
/// The active connection for the session. /// The active connection for the session.
connection: *pg.Conn, connection: *pg.Conn,
/// The count of active transactions for the session.
activeTransactions: usize = 0,
/// Execute a comptime-known SQL command for the current session. /// Execute a comptime-known SQL command for the current session.
fn exec(self: Self, comptime sql: []const u8) !void { fn exec(self: Self, comptime sql: []const u8) !void {
_ = self.connection.exec(sql, .{}) catch |err| { _ = self.connection.exec(sql, .{}) catch |err| {
@ -32,25 +29,11 @@ pub const Session = struct {
try self.exec("ROLLBACK;"); try self.exec("ROLLBACK;");
} }
/// Rollback all active transactions.
pub fn rollbackAll(self: Self) !void {
for (0..self.activeTransactions) |_| {
self.rollbackTransaction();
}
}
/// Commit the current transaction. /// Commit the current transaction.
pub fn commitTransaction(self: Self) !void { pub fn commitTransaction(self: Self) !void {
try self.exec("COMMIT;"); 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. /// Create a new savepoint with the given name.
pub fn savepoint(self: Self, comptime _savepoint: []const u8) !void { pub fn savepoint(self: Self, comptime _savepoint: []const u8) !void {
try self.exec("SAVEPOINT " ++ _savepoint ++ ";"); try self.exec("SAVEPOINT " ++ _savepoint ++ ";");

View file

@ -1,5 +1,5 @@
const std = @import("std"); const std = @import("std");
const ZrmError = @import("errors.zig").ZrmError; const errors = @import("errors.zig");
/// A structure with SQL and its parameters. /// A structure with SQL and its parameters.
pub const RawQuery = struct { pub const RawQuery = struct {
@ -120,7 +120,7 @@ pub const RawQueryParameter = union(enum) {
null: void, null: void,
/// Convert any value to a query parameter. /// Convert any value to a query parameter.
pub fn fromValue(value: anytype) ZrmError!RawQueryParameter { pub fn fromValue(value: anytype) errors.ZrmError!RawQueryParameter {
// Get given value type. // Get given value type.
const valueType = @typeInfo(@TypeOf(value)); const valueType = @typeInfo(@TypeOf(value));
@ -138,7 +138,7 @@ pub const RawQueryParameter = union(enum) {
if (pointer.child == u8) { if (pointer.child == u8) {
return .{ .string = value }; return .{ .string = value };
} else { } else {
return ZrmError.UnsupportedTableType; return errors.ZrmError.UnsupportedTableType;
} }
} }
}, },
@ -154,7 +154,7 @@ pub const RawQueryParameter = union(enum) {
return .{ .null = true }; return .{ .null = true };
} }
}, },
else => return ZrmError.UnsupportedTableType else => return errors.ZrmError.UnsupportedTableType
}; };
} }
}; };

View file

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const pg = @import("pg"); const pg = @import("pg");
const zollections = @import("zollections"); const zollections = @import("zollections");
const ZrmError = @import("errors.zig").ZrmError; const errors = @import("errors.zig");
const database = @import("database.zig"); const database = @import("database.zig");
const postgresql = @import("postgresql.zig"); const postgresql = @import("postgresql.zig");
const _sql = @import("sql.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. /// 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) { if (_select.len == 0) {
return ZrmError.AtLeastOneSelectionRequired; return errors.AtLeastOneSelectionRequired;
} }
self.returning(.{ self.returning(.{
// Join selected columns. // Join selected columns.
.sql = try std.mem.join(self.arena.allocator(), ", ", _select), .sql = std.mem.join(self.arena.allocator(), ", ", _select),
.params = &[_]_sql.RawQueryParameter{}, // No parameters. .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 { pub fn buildSql(self: *Self) !void {
if (self.updateConfig.value) |_| {} else { if (self.updateConfig.value) |_| {} else {
// Updated values must be set. // Updated values must be set.
return ZrmError.UpdatedValuesRequired; return errors.ZrmError.UpdatedValuesRequired;
} }
// Start parameter counter at 1. // Start parameter counter at 1.