diff --git a/src/insert.zig b/src/insert.zig index ceba9d5..b5c772c 100644 --- a/src/insert.zig +++ b/src/insert.zig @@ -334,30 +334,8 @@ pub fn RepositoryInsert(comptime Model: type, comptime TableShape: type, comptim defer self.connection.release(); defer queryResult.deinit(); - //TODO deduplicate this in postgresql.zig, we could do it if Mapper type was exposed. - //TODO make a generic mapper and do it in repository.zig? - // Create an arena for mapper data. - var mapperArena = std.heap.ArenaAllocator.init(allocator); - // Get result mapper. - const mapper = queryResult.mapper(TableShape, .{ .allocator = mapperArena.allocator() }); - - // Initialize models list. - var models = std.ArrayList(*Model).init(allocator); - defer models.deinit(); - - // Get all raw models from the result mapper. - while (try mapper.next()) |rawModel| { - // Parse each raw model from the mapper. - const model = try allocator.create(Model); - model.* = try repositoryConfig.fromSql(rawModel); - try models.append(model); - } - - // Return a result with the models. - return repository.RepositoryResult(Model).init(allocator, - zollections.Collection(Model).init(allocator, try models.toOwnedSlice()), - mapperArena, - ); + // Map query results. + return postgresql.mapResults(Model, TableShape, repositoryConfig, allocator, queryResult); } /// Initialize a new repository insert query. diff --git a/src/postgresql.zig b/src/postgresql.zig index bd3a896..5b9344d 100644 --- a/src/postgresql.zig +++ b/src/postgresql.zig @@ -1,5 +1,6 @@ const std = @import("std"); const pg = @import("pg"); +const zollections = @import("zollections"); const global = @import("global.zig"); const errors = @import("errors.zig"); const database = @import("database.zig"); @@ -55,3 +56,33 @@ pub fn handleRawPostgresqlError(err: anyerror, connection: *pg.Conn) anyerror { return err; } } + +/// Generic query results mapping. +pub fn mapResults(comptime Model: type, comptime TableShape: type, + repositoryConfig: repository.RepositoryConfiguration(Model, TableShape), + allocator: std.mem.Allocator, queryResult: *pg.Result) !repository.RepositoryResult(Model) +{ + //TODO make a generic mapper and do it in repository.zig? + // Create an arena for mapper data. + var mapperArena = std.heap.ArenaAllocator.init(allocator); + // Get result mapper. + const mapper = queryResult.mapper(TableShape, .{ .allocator = mapperArena.allocator() }); + + // Initialize models list. + var models = std.ArrayList(*Model).init(allocator); + defer models.deinit(); + + // Get all raw models from the result mapper. + while (try mapper.next()) |rawModel| { + // Parse each raw model from the mapper. + const model = try allocator.create(Model); + model.* = try repositoryConfig.fromSql(rawModel); + try models.append(model); + } + + // Return a result with the models. + return repository.RepositoryResult(Model).init(allocator, + zollections.Collection(Model).init(allocator, try models.toOwnedSlice()), + mapperArena, + ); +} diff --git a/src/query.zig b/src/query.zig index 0234a13..d2a6cf1 100644 --- a/src/query.zig +++ b/src/query.zig @@ -220,30 +220,8 @@ pub fn RepositoryQuery(comptime Model: type, comptime TableShape: type, comptime defer self.connection.release(); defer queryResult.deinit(); - //TODO deduplicate this in postgresql.zig, we could do it if Mapper type was exposed. - //TODO make a generic mapper and do it in repository.zig? - // Create an arena for mapper data. - var mapperArena = std.heap.ArenaAllocator.init(allocator); - // Get result mapper. - const mapper = queryResult.mapper(TableShape, .{ .allocator = mapperArena.allocator() }); - - // Initialize models list. - var models = std.ArrayList(*Model).init(allocator); - defer models.deinit(); - - // Get all raw models from the result mapper. - while (try mapper.next()) |rawModel| { - // Parse each raw model from the mapper. - const model = try allocator.create(Model); - model.* = try repositoryConfig.fromSql(rawModel); - try models.append(model); - } - - // Return a result with the models. - return repository.RepositoryResult(Model).init(allocator, - zollections.Collection(Model).init(allocator, try models.toOwnedSlice()), - mapperArena, - ); + // Map query results. + return postgresql.mapResults(Model, TableShape, repositoryConfig, allocator, queryResult); } /// Initialize a new repository query. diff --git a/src/update.zig b/src/update.zig index 87b2d9b..a24a2c9 100644 --- a/src/update.zig +++ b/src/update.zig @@ -308,30 +308,8 @@ pub fn RepositoryUpdate(comptime Model: type, comptime TableShape: type, comptim defer self.connection.release(); defer queryResult.deinit(); - //TODO deduplicate this in postgresql.zig, we could do it if Mapper type was exposed. - //TODO make a generic mapper and do it in repository.zig? - // Create an arena for mapper data. - var mapperArena = std.heap.ArenaAllocator.init(allocator); - // Get result mapper. - const mapper = queryResult.mapper(TableShape, .{ .allocator = mapperArena.allocator() }); - - // Initialize models list. - var models = std.ArrayList(*Model).init(allocator); - defer models.deinit(); - - // Get all raw models from the result mapper. - while (try mapper.next()) |rawModel| { - // Parse each raw model from the mapper. - const model = try allocator.create(Model); - model.* = try repositoryConfig.fromSql(rawModel); - try models.append(model); - } - - // Return a result with the models. - return repository.RepositoryResult(Model).init(allocator, - zollections.Collection(Model).init(allocator, try models.toOwnedSlice()), - mapperArena, - ); + // Map query results. + return postgresql.mapResults(Model, TableShape, repositoryConfig, allocator, queryResult); } /// Initialize a new repository update query.