diff --git a/src/insert.zig b/src/insert.zig index e1c0c4e..bf06341 100644 --- a/src/insert.zig +++ b/src/insert.zig @@ -14,6 +14,36 @@ pub fn Insertable(comptime ValueType: type) type { }; } +/// Build an insertable structure type from a normal structure. +pub fn InsertableStruct(comptime StructType: type) type { + // Get type info of the given structure. + const typeInfo = @typeInfo(StructType); + + // Initialize fields of the insertable struct. + var newFields: [typeInfo.Struct.fields.len]std.builtin.Type.StructField = undefined; + for (typeInfo.Struct.fields, &newFields) |field, *newField| { + // Create a new field for each field of the given struct. + const newFieldType = Insertable(field.type); + newField.* = std.builtin.Type.StructField{ + .name = field.name, + .type = newFieldType, + .default_value = null, + .is_comptime = false, + .alignment = @alignOf(newFieldType), + }; + } + + // Return the insertable structure type. + return @Type(std.builtin.Type{ + .Struct = .{ + .layout = .auto, + .decls = &[0]std.builtin.Type.Declaration{}, + .fields = &newFields, + .is_tuple = false, + }, + }); +} + /// Repository insert query configuration structure. pub fn RepositoryInsertConfiguration(comptime InsertShape: type) type { return struct { diff --git a/src/root.zig b/src/root.zig index ba51afe..e70a877 100644 --- a/src/root.zig +++ b/src/root.zig @@ -10,6 +10,7 @@ pub const RepositoryConfiguration = repository.RepositoryConfiguration; pub const RepositoryResult = repository.RepositoryResult; pub const Insertable = insert.Insertable; +pub const InsertableStruct = insert.InsertableStruct; pub const QueryParameter = _sql.QueryParameter; pub const SqlParams = _sql.SqlParams; diff --git a/tests/composite.zig b/tests/composite.zig index 7fe85aa..9b46621 100644 --- a/tests/composite.zig +++ b/tests/composite.zig @@ -59,10 +59,10 @@ const CompositeModelRepository = zrm.Repository(CompositeModel, CompositeModelTa .table = "composite_models", // Insert shape used by default for inserts in the repository. - .insertShape = struct { - secondcol: zrm.Insertable([]const u8), - label: zrm.Insertable([]const u8), - }, + .insertShape = zrm.InsertableStruct(struct { + secondcol: []const u8, + label: []const u8, + }), .key = &[_][]const u8{"firstcol", "secondcol"},