Skip to content

Commit c20053b

Browse files
feat: generate missing tests
1 parent 131b3f8 commit c20053b

42 files changed

Lines changed: 592 additions & 106 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CodeGenerator/Generators/DataClassesGen.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace SqlcGenCsharp.Generators;
1010

1111
internal class DataClassesGen(DbDriver dbDriver)
1212
{
13-
public MemberDeclarationSyntax Generate(string name, ClassMember? classMember, IList<Column> columns, Options options, Query? query = null)
13+
public MemberDeclarationSyntax Generate(string name, ClassMember? classMember, IList<Column> columns, Options options, Query? query)
1414
{
1515
var className = classMember is null ? name : classMember.Value.Name(name);
1616
if (options.DotnetFramework.IsDotnetCore() && !options.UseDapper)
@@ -58,7 +58,7 @@ bool RequiredModifierNeeded(Column column)
5858
return false;
5959
if (column.EmbedTable != null)
6060
return true;
61-
return column.NotNull;
61+
return dbDriver.IsColumnNotNull(column, query);
6262
}
6363
}
6464

CodeGenerator/Generators/ModelsGen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private MemberDeclarationSyntax[] GenerateDataClasses(Dictionary<string, Diction
4646
from schemaTables in tables
4747
from table in schemaTables.Value
4848
let className = table.Value.Rel.Name.ToModelName(table.Value.Rel.Schema, dbDriver.DefaultSchema)
49-
select DataClassesGen.Generate(className, null, table.Value.Columns, dbDriver.Options)
49+
select DataClassesGen.Generate(className, null, table.Value.Columns, dbDriver.Options, null)
5050
).ToArray();
5151
}
5252

CodeGenerator/Generators/QueriesGen.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,14 @@ private IEnumerable<MemberDeclarationSyntax> GetMembersForSingleQuery(Query quer
8989
private MemberDeclarationSyntax? GetQueryColumnsDataclass(Query query)
9090
{
9191
if (query.Columns.Count <= 0) return null;
92-
return DataClassesGen.Generate(query.Name, ClassMember.Row, query.Columns, dbDriver.Options);
92+
return DataClassesGen.Generate(query.Name, ClassMember.Row, query.Columns, dbDriver.Options, query);
9393
}
9494

9595
private MemberDeclarationSyntax? GetQueryParamsDataclass(Query query)
9696
{
9797
if (query.Params.Count <= 0) return null;
9898
var columns = query.Params.Select(p => dbDriver.GetColumnFromParam(p, query)).ToList();
99-
return DataClassesGen.Generate(query.Name, ClassMember.Args, columns, dbDriver.Options);
99+
return DataClassesGen.Generate(query.Name, ClassMember.Args, columns, dbDriver.Options, query);
100100
}
101101

102102
private MemberDeclarationSyntax? GetQueryTextConstant(Query query)

Drivers/DbDriver.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public string AddNullableSuffixIfNeeded(string csharpType, bool notNull)
133133
public string GetCsharpType(Column column, Query? query)
134134
{
135135
var csharpType = GetCsharpTypeWithoutNullableSuffix(column, query);
136-
return AddNullableSuffixIfNeeded(csharpType, column.NotNull);
136+
return AddNullableSuffixIfNeeded(csharpType, IsColumnNotNull(column, query));
137137
}
138138

139139
private string GetCsharpTypeWithoutNullableSuffix(Column column, Query? query)
@@ -285,8 +285,21 @@ protected bool BatchQueryExists()
285285
return Queries.Any(q => q.Cmd is ":copyfrom");
286286
}
287287

288-
private OverrideOption? FindOverrideForQueryColumn(Query query, Column column)
288+
public OverrideOption? FindOverrideForQueryColumn(Query query, Column column)
289289
{
290290
return Options.Overrides.FirstOrDefault(o => o.Column.Equals($"{query.Name}:{column.Name}"));
291291
}
292+
293+
/// <summary>
294+
/// If the column data type is overridden, we need to check for nulls in generated code
295+
/// </summary>
296+
/// <param name="column"></param>
297+
/// <param name="query"></param>
298+
/// <returns>Adjusted not null value</returns>
299+
public bool IsColumnNotNull(Column column, Query? query)
300+
{
301+
if (query is null)
302+
return column.NotNull;
303+
return column.NotNull && FindOverrideForQueryColumn(query, column) is null;
304+
}
292305
}

Drivers/Generators/CommonGen.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,25 +135,6 @@ string GetAsSimpleAssignment(Column column, int ordinal, Query query)
135135
return $"{column.Name.ToPascalCase()} = {readExpression}";
136136
}
137137

138-
string GetReadExpression(Column column, int ordinal, Query query)
139-
{
140-
return column.NotNull
141-
? dbDriver.GetColumnReader(column, ordinal, query)
142-
: $"{CheckNullExpression(ordinal)} ? {GetNullExpression(column, query)} : {dbDriver.GetColumnReader(column, ordinal, query)}";
143-
}
144-
145-
string GetNullExpression(Column column, Query? query)
146-
{
147-
var csharpType = dbDriver.GetCsharpType(column, query);
148-
if (dbDriver.Options.DotnetFramework.IsDotnetCore()) return "null";
149-
return dbDriver.IsTypeNullable(csharpType) ? $"({csharpType}) null" : "null";
150-
}
151-
152-
string CheckNullExpression(int ordinal)
153-
{
154-
return $"{Variable.Reader.AsVarName()}.IsDBNull({ordinal})";
155-
}
156-
157138
string InstantiateDataclassInternal(string name, IEnumerable<string> fieldsInit)
158139
{
159140
return $$"""
@@ -164,4 +145,23 @@ string InstantiateDataclassInternal(string name, IEnumerable<string> fieldsInit)
164145
""";
165146
}
166147
}
148+
149+
private string GetNullExpression(Column column, Query? query)
150+
{
151+
var csharpType = dbDriver.GetCsharpType(column, query);
152+
if (dbDriver.Options.DotnetFramework.IsDotnetCore()) return "null";
153+
return dbDriver.IsTypeNullable(csharpType) ? $"({csharpType}) null" : "null";
154+
}
155+
156+
private static string CheckNullExpression(int ordinal)
157+
{
158+
return $"{Variable.Reader.AsVarName()}.IsDBNull({ordinal})";
159+
}
160+
161+
private string GetReadExpression(Column column, int ordinal, Query query)
162+
{
163+
if (dbDriver.IsColumnNotNull(column, query))
164+
return dbDriver.GetColumnReader(column, ordinal, query);
165+
return $"{CheckNullExpression(ordinal)} ? {GetNullExpression(column, query)} : {dbDriver.GetColumnReader(column, ordinal, query)}";
166+
}
167167
}

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dotnet-publish-process: dotnet-build-process
2929
dotnet publish LocalRunner -c release --output dist/
3030

3131
sqlc-generate-process: dotnet-publish-process
32+
./scripts/sync_sqlc_options.sh
3233
sqlc -f sqlc.local.yaml generate
3334

3435
# WASM type plugin

end2end/EndToEndScaffold/Config.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ internal static class Config
9797
KnownTestType.MySqlBinaryDataTypes,
9898
KnownTestType.MySqlEnumDataType,
9999
KnownTestType.MySqlScopedSchemaEnum,
100+
KnownTestType.MySqlDataTypesOverride,
100101

101102
KnownTestType.MySqlStringCopyFrom,
102103
KnownTestType.MySqlIntegerCopyFrom,
@@ -132,6 +133,7 @@ internal static class Config
132133
KnownTestType.MySqlBinaryDataTypes,
133134
KnownTestType.MySqlEnumDataType,
134135
KnownTestType.MySqlScopedSchemaEnum,
136+
KnownTestType.MySqlDataTypesOverride,
135137

136138
KnownTestType.MySqlStringCopyFrom,
137139
KnownTestType.MySqlIntegerCopyFrom,
@@ -166,6 +168,7 @@ internal static class Config
166168
KnownTestType.PostgresDateTimeDataTypes,
167169
KnownTestType.PostgresArrayDataTypes,
168170
KnownTestType.PostgresGeoDataTypes,
171+
KnownTestType.PostgresDataTypesOverride,
169172

170173
KnownTestType.PostgresStringCopyFrom,
171174
KnownTestType.PostgresIntegerCopyFrom,
@@ -199,6 +202,7 @@ internal static class Config
199202
KnownTestType.PostgresDateTimeDataTypes,
200203
KnownTestType.PostgresArrayDataTypes,
201204
KnownTestType.PostgresGeoDataTypes,
205+
KnownTestType.PostgresDataTypesOverride,
202206

203207
KnownTestType.PostgresStringCopyFrom,
204208
KnownTestType.PostgresIntegerCopyFrom,
@@ -226,7 +230,8 @@ internal static class Config
226230
KnownTestType.NargNull,
227231
KnownTestType.NargNotNull,
228232
KnownTestType.SqliteDataTypes,
229-
KnownTestType.SqliteCopyFrom
233+
KnownTestType.SqliteCopyFrom,
234+
KnownTestType.SqliteDataTypesOverride
230235
]
231236
}
232237
},
@@ -248,7 +253,8 @@ internal static class Config
248253
KnownTestType.NargNull,
249254
KnownTestType.NargNotNull,
250255
KnownTestType.SqliteDataTypes,
251-
KnownTestType.SqliteCopyFrom
256+
KnownTestType.SqliteCopyFrom,
257+
KnownTestType.SqliteDataTypesOverride
252258
]
253259
}
254260
},

end2end/EndToEndScaffold/Templates/MySqlTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,46 @@ private static bool SingularEquals(QuerySql.GetFirstExtendedBioByTypeRow x, Quer
580580
return x.AuthorName.Equals(y.AuthorName) && x.Name.Equals(y.Name) && x.BioType.Equals(y.BioType);
581581
}
582582
"""
583+
},
584+
[KnownTestType.MySqlDataTypesOverride] = new TestImpl
585+
{
586+
Impl = $$"""
587+
[Test]
588+
[TestCase(-54355, 9787876578, "Scream of the Butterfly", "2025-06-29 12:00:00")]
589+
[TestCase(null, null, null, null)]
590+
public async Task TestMySqlDataTypesOverride(
591+
int? cInt,
592+
long? cBigint,
593+
string cVarchar,
594+
DateTime? cTimestamp)
595+
{
596+
await QuerySql.InsertMysqlTypes(new QuerySql.InsertMysqlTypesArgs
597+
{
598+
CInt = cInt,
599+
CBigint = cBigint,
600+
CVarchar = cVarchar,
601+
CTimestamp = cTimestamp
602+
});
603+
var expected = new QuerySql.GetMysqlFunctionsRow
604+
{
605+
MaxInt = cInt,
606+
MaxBigint = cBigint,
607+
MaxVarchar = cVarchar,
608+
MaxTimestamp = cTimestamp
609+
};
610+
611+
var actual = await QuerySql.GetMysqlFunctions();
612+
AssertSingularEquals(expected, actual{{Consts.UnknownRecordValuePlaceholder}});
613+
}
614+
615+
private static void AssertSingularEquals(QuerySql.GetMysqlFunctionsRow expected, QuerySql.GetMysqlFunctionsRow actual)
616+
{
617+
Assert.That(actual.MaxInt, Is.EqualTo(expected.MaxInt));
618+
Assert.That(actual.MaxBigint, Is.EqualTo(expected.MaxBigint));
619+
Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar));
620+
Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp));
621+
}
622+
"""
583623
}
584624
};
585625
}

end2end/EndToEndScaffold/Templates/PostgresTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,42 @@ public async Task TestPostgresGeoTypes(NpgsqlPoint? cPoint, NpgsqlLine? cLine, N
484484
}
485485
"""
486486
},
487+
[KnownTestType.PostgresDataTypesOverride] = new TestImpl
488+
{
489+
Impl = $$"""
490+
[Test]
491+
[TestCase(-54355, "White Light from the Mouth of Infinity", "2022-10-2 15:44:01+09:00")]
492+
[TestCase(null, null, null)]
493+
public async Task TestPostgresDataTypesOverride(
494+
int? cInteger,
495+
string cVarchar,
496+
DateTime? cTimestamp)
497+
{
498+
await QuerySql.InsertPostgresTypes(new QuerySql.InsertPostgresTypesArgs
499+
{
500+
CInteger = cInteger,
501+
CVarchar = cVarchar,
502+
CTimestamp = cTimestamp
503+
});
504+
505+
var expected = new QuerySql.GetPostgresFunctionsRow
506+
{
507+
MaxInteger = cInteger,
508+
MaxVarchar = cVarchar,
509+
MaxTimestamp = cTimestamp
510+
};
487511
512+
var actual = await QuerySql.GetPostgresFunctions();
513+
AssertSingularEquals(expected, actual{{Consts.UnknownRecordValuePlaceholder}});
514+
}
515+
516+
private static void AssertSingularEquals(QuerySql.GetPostgresFunctionsRow expected, QuerySql.GetPostgresFunctionsRow actual)
517+
{
518+
Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger));
519+
Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar));
520+
Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp));
521+
}
522+
"""
523+
}
488524
};
489525
}

end2end/EndToEndScaffold/Templates/SqliteTests.cs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static class SqliteTests
1414
[TestCase(null, null, null, new byte[] { })]
1515
[TestCase(null, null, null, null)]
1616
public async Task TestSqliteTypes(
17-
int cInteger,
17+
int? cInteger,
1818
decimal? cReal,
1919
string cText,
2020
byte[] cBlob)
@@ -93,9 +93,35 @@ private static void AssertSingularEquals(QuerySql.GetSqliteTypesCntRow expected,
9393
{
9494
Impl = $$"""
9595
[Test]
96-
public async Task TestSqliteDataTypesOverride()
96+
[TestCase(-54355, 9787.66, "Have One On Me")]
97+
[TestCase(null, null, null)]
98+
public async Task TestSqliteDataTypesOverride(
99+
int? cInteger,
100+
decimal? cReal,
101+
string cText)
97102
{
98-
var actual = await QuerySql.GetSqliteTypes();
103+
await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs
104+
{
105+
CInteger = cInteger,
106+
CReal = cReal,
107+
CText = cText
108+
});
109+
110+
var expected = new QuerySql.GetSqliteFunctionsRow
111+
{
112+
MaxInteger = cInteger,
113+
MaxReal = cReal,
114+
MaxText = cText
115+
};
116+
var actual = await QuerySql.GetSqliteFunctions();
117+
AssertSingularEquals(expected, actual{{Consts.UnknownRecordValuePlaceholder}});
118+
}
119+
120+
private static void AssertSingularEquals(QuerySql.GetSqliteFunctionsRow expected, QuerySql.GetSqliteFunctionsRow actual)
121+
{
122+
Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger));
123+
Assert.That(actual.MaxReal, Is.EqualTo(expected.MaxReal));
124+
Assert.That(actual.MaxText, Is.EqualTo(expected.MaxText));
99125
}
100126
"""
101127
}

0 commit comments

Comments
 (0)