Skip to content

Commit dd09c22

Browse files
[release] [minor] add non dapper implementation when Dapper is enabled for queries with sqlc.embed (#209)
1 parent 8fe9ae4 commit dd09c22

File tree

17 files changed

+685
-34
lines changed

17 files changed

+685
-34
lines changed

Drivers/Generators/CommonGen.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public string InstantiateDataclass(Column[] columns, string returnInterface)
102102
? $"{tableFieldType}{value}" : tableFieldType;
103103
seenEmbed.TryAdd(tableFieldType, 1);
104104
seenEmbed[tableFieldType]++;
105+
105106
var tableColumnsInit = GetAsEmbeddedTableColumnAssignment(column, actualOrdinal);
106107
columnsInit.Add($"{tableFieldName} = {InstantiateDataclassInternal(tableFieldType, tableColumnsInit)}");
107108
actualOrdinal += tableColumnsInit.Length;
@@ -119,10 +120,16 @@ string[] GetAsEmbeddedTableColumnAssignment(Column tableColumn, int ordinal)
119120

120121
string GetAsSimpleAssignment(Column column, int ordinal)
121122
{
122-
var readExpression = column.NotNull
123+
var readExpression = GetReadExpression(column, ordinal);
124+
return $"{column.Name.ToPascalCase()} = {readExpression}";
125+
}
126+
127+
string GetReadExpression(Column column, int ordinal)
128+
{
129+
return column.NotNull
123130
? dbDriver.GetColumnReader(column, ordinal)
124131
: $"{CheckNullExpression(ordinal)} ? {GetNullExpression(column)} : {dbDriver.GetColumnReader(column, ordinal)}";
125-
return $"{column.Name.ToPascalCase()} = {readExpression}";
132+
;
126133
}
127134

128135
string GetNullExpression(Column column)

Drivers/Generators/ManyDeclareGen.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ private string GetMethodBody(string queryTextConstant, string returnInterface, Q
2727
var (establishConnection, connectionOpen) = dbDriver.EstablishConnection(query);
2828
var sqlTextTransform = CommonGen.GetSqlTransformations(query, queryTextConstant);
2929
var resultVar = Variable.Result.AsVarName();
30-
return dbDriver.Options.UseDapper ? GetAsDapper() : GetAsDriver();
30+
var anyEmbeddedTableExists = query.Columns.Any(c => c.EmbedTable is not null);
31+
return dbDriver.Options.UseDapper && !anyEmbeddedTableExists
32+
? GetAsDapper()
33+
: GetAsDriver();
3134

3235
string GetAsDapper()
3336
{

Drivers/Generators/OneDeclareGen.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@ private string GetMethodBody(string queryTextConstant, string returnInterface, Q
2828
var sqlTextTransform = CommonGen.GetSqlTransformations(query, queryTextConstant);
2929
var connectionVar = Variable.Connection.AsVarName();
3030
var resultVar = Variable.Result.AsVarName();
31-
return dbDriver.Options.UseDapper ? GetAsDapper() : GetAsDriver();
31+
var anyEmbeddedTableExists = query.Columns.Any(c => c.EmbedTable is not null);
32+
return dbDriver.Options.UseDapper && !anyEmbeddedTableExists
33+
? GetAsDapper()
34+
: GetAsDriver();
3235

3336
string GetAsDapper()
3437
{
3538
var dapperParamsSection = CommonGen.ConstructDapperParamsDict(query.Params);
3639
var dapperArgs = dapperParamsSection != string.Empty ? $", {Variable.QueryParams.AsVarName()}" : string.Empty;
3740
var returnType = dbDriver.AddNullableSuffix(returnInterface, false);
41+
3842
return $$"""
3943
using ({{establishConnection}})
4044
{{{sqlTextTransform}}{{dapperParamsSection}}

Drivers/NpgsqlDriver.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ public override ConnectionGenCommands EstablishConnection(Query query)
9494
$"var ds = NpgsqlDataSource.Create({connectionStringField})",
9595
$"var {Variable.Connection.AsVarName()} = ds.CreateConnection()"
9696
);
97-
if (Options.UseDapper)
97+
98+
var embedTableExists = query.Columns.Any(c => c.EmbedTable is not null);
99+
if (Options.UseDapper && !embedTableExists)
98100
return new ConnectionGenCommands(
99101
$"var {Variable.Connection.AsVarName()} = new NpgsqlConnection({connectionStringField})",
100102
""

end2end/EndToEndScaffold/Config.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ internal static class Config
5656
KnownTestType.Exec,
5757
KnownTestType.ExecRows,
5858
KnownTestType.ExecLastId,
59+
KnownTestType.JoinEmbed,
60+
KnownTestType.SelfJoinEmbed,
5961
KnownTestType.Slice,
6062
KnownTestType.MultipleSlices
6163
]
@@ -87,7 +89,9 @@ internal static class Config
8789
KnownTestType.Many,
8890
KnownTestType.Exec,
8991
KnownTestType.ExecRows,
90-
KnownTestType.ExecLastId
92+
KnownTestType.ExecLastId,
93+
KnownTestType.JoinEmbed,
94+
KnownTestType.SelfJoinEmbed
9195
]
9296
}
9397
},
@@ -120,6 +124,8 @@ internal static class Config
120124
KnownTestType.Exec,
121125
KnownTestType.ExecRows,
122126
KnownTestType.ExecLastId,
127+
KnownTestType.JoinEmbed,
128+
KnownTestType.SelfJoinEmbed,
123129
KnownTestType.Slice,
124130
KnownTestType.MultipleSlices
125131
]

end2end/EndToEndTests/MySqlConnectorDapperTester.generated.cs

+46
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,52 @@ public async Task TestExecLastId()
7676
Assert.That(actual is { Name: DataGenerator.GenericAuthor, Bio: DataGenerator.GenericQuote1 });
7777
}
7878

79+
[Test]
80+
public async Task TestJoinEmbed()
81+
{
82+
var createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
83+
{
84+
Name = DataGenerator.BojackAuthor,
85+
Bio = DataGenerator.BojackTheme
86+
};
87+
var bojackAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
88+
var createBookArgs = new QuerySql.CreateBookArgs
89+
{
90+
Name = DataGenerator.BojackBookTitle,
91+
AuthorId = bojackAuthorId
92+
};
93+
await QuerySql.CreateBook(createBookArgs);
94+
createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
95+
{
96+
Name = DataGenerator.DrSeussAuthor,
97+
Bio = DataGenerator.DrSeussQuote
98+
};
99+
var drSeussAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
100+
createBookArgs = new QuerySql.CreateBookArgs
101+
{
102+
Name = DataGenerator.DrSeussBookTitle,
103+
AuthorId = drSeussAuthorId
104+
};
105+
await QuerySql.CreateBook(createBookArgs);
106+
var actual = await QuerySql.ListAllAuthorsBooks();
107+
Assert.That(actual is [{ Author: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, }, Book.Name: DataGenerator.BojackBookTitle, }, { Author: { Name: DataGenerator.DrSeussAuthor, Bio: DataGenerator.DrSeussQuote, }, Book.Name: DataGenerator.DrSeussBookTitle, }]);
108+
}
109+
110+
[Test]
111+
public async Task TestSelfJoinEmbed()
112+
{
113+
var createAuthorArgs = new QuerySql.CreateAuthorArgs
114+
{
115+
Name = DataGenerator.BojackAuthor,
116+
Bio = DataGenerator.BojackTheme
117+
};
118+
await QuerySql.CreateAuthor(createAuthorArgs);
119+
await QuerySql.CreateAuthor(createAuthorArgs);
120+
var actual = await QuerySql.GetDuplicateAuthors();
121+
Assert.That(actual is [{ Author: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, }, Author2: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, } }]);
122+
Assert.That(actual[0].Author.Id, Is.Not.EqualTo(actual[0].Author2.Id));
123+
}
124+
79125
[Test]
80126
public async Task TestSliceIds()
81127
{

end2end/EndToEndTests/NpgsqlDapperTester.generated.cs

+46
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,51 @@ public async Task TestExecLastId()
7575
var actual = await QuerySql.GetAuthorById(getAuthorByIdArgs);
7676
Assert.That(actual is { Name: DataGenerator.GenericAuthor, Bio: DataGenerator.GenericQuote1 });
7777
}
78+
79+
[Test]
80+
public async Task TestJoinEmbed()
81+
{
82+
var createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
83+
{
84+
Name = DataGenerator.BojackAuthor,
85+
Bio = DataGenerator.BojackTheme
86+
};
87+
var bojackAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
88+
var createBookArgs = new QuerySql.CreateBookArgs
89+
{
90+
Name = DataGenerator.BojackBookTitle,
91+
AuthorId = bojackAuthorId
92+
};
93+
await QuerySql.CreateBook(createBookArgs);
94+
createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
95+
{
96+
Name = DataGenerator.DrSeussAuthor,
97+
Bio = DataGenerator.DrSeussQuote
98+
};
99+
var drSeussAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
100+
createBookArgs = new QuerySql.CreateBookArgs
101+
{
102+
Name = DataGenerator.DrSeussBookTitle,
103+
AuthorId = drSeussAuthorId
104+
};
105+
await QuerySql.CreateBook(createBookArgs);
106+
var actual = await QuerySql.ListAllAuthorsBooks();
107+
Assert.That(actual is [{ Author: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, }, Book.Name: DataGenerator.BojackBookTitle, }, { Author: { Name: DataGenerator.DrSeussAuthor, Bio: DataGenerator.DrSeussQuote, }, Book.Name: DataGenerator.DrSeussBookTitle, }]);
108+
}
109+
110+
[Test]
111+
public async Task TestSelfJoinEmbed()
112+
{
113+
var createAuthorArgs = new QuerySql.CreateAuthorArgs
114+
{
115+
Name = DataGenerator.BojackAuthor,
116+
Bio = DataGenerator.BojackTheme
117+
};
118+
await QuerySql.CreateAuthor(createAuthorArgs);
119+
await QuerySql.CreateAuthor(createAuthorArgs);
120+
var actual = await QuerySql.GetDuplicateAuthors();
121+
Assert.That(actual is [{ Author: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, }, Author2: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, } }]);
122+
Assert.That(actual[0].Author.Id, Is.Not.EqualTo(actual[0].Author2.Id));
123+
}
78124
}
79125
}

end2end/EndToEndTests/SqliteDapperTester.generated.cs

+46
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,52 @@ public async Task TestExecLastId()
7676
Assert.That(actual is { Name: DataGenerator.GenericAuthor, Bio: DataGenerator.GenericQuote1 });
7777
}
7878

79+
[Test]
80+
public async Task TestJoinEmbed()
81+
{
82+
var createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
83+
{
84+
Name = DataGenerator.BojackAuthor,
85+
Bio = DataGenerator.BojackTheme
86+
};
87+
var bojackAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
88+
var createBookArgs = new QuerySql.CreateBookArgs
89+
{
90+
Name = DataGenerator.BojackBookTitle,
91+
AuthorId = bojackAuthorId
92+
};
93+
await QuerySql.CreateBook(createBookArgs);
94+
createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
95+
{
96+
Name = DataGenerator.DrSeussAuthor,
97+
Bio = DataGenerator.DrSeussQuote
98+
};
99+
var drSeussAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
100+
createBookArgs = new QuerySql.CreateBookArgs
101+
{
102+
Name = DataGenerator.DrSeussBookTitle,
103+
AuthorId = drSeussAuthorId
104+
};
105+
await QuerySql.CreateBook(createBookArgs);
106+
var actual = await QuerySql.ListAllAuthorsBooks();
107+
Assert.That(actual is [{ Author: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, }, Book.Name: DataGenerator.BojackBookTitle, }, { Author: { Name: DataGenerator.DrSeussAuthor, Bio: DataGenerator.DrSeussQuote, }, Book.Name: DataGenerator.DrSeussBookTitle, }]);
108+
}
109+
110+
[Test]
111+
public async Task TestSelfJoinEmbed()
112+
{
113+
var createAuthorArgs = new QuerySql.CreateAuthorArgs
114+
{
115+
Name = DataGenerator.BojackAuthor,
116+
Bio = DataGenerator.BojackTheme
117+
};
118+
await QuerySql.CreateAuthor(createAuthorArgs);
119+
await QuerySql.CreateAuthor(createAuthorArgs);
120+
var actual = await QuerySql.GetDuplicateAuthors();
121+
Assert.That(actual is [{ Author: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, }, Author2: { Name: DataGenerator.BojackAuthor, Bio: DataGenerator.BojackTheme, } }]);
122+
Assert.That(actual[0].Author.Id, Is.Not.EqualTo(actual[0].Author2.Id));
123+
}
124+
79125
[Test]
80126
public async Task TestSliceIds()
81127
{

end2end/EndToEndTestsLegacy/MySqlConnectorDapperTester.generated.cs

+117
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,123 @@ private static bool Equals(QuerySql.GetAuthorByIdRow x, QuerySql.GetAuthorByIdRo
118118
return x.Id.Equals(y.Id) && x.Name.Equals(y.Name) && x.Bio.Equals(y.Bio);
119119
}
120120

121+
[Test]
122+
public async Task TestJoinEmbed()
123+
{
124+
var createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
125+
{
126+
Name = DataGenerator.BojackAuthor,
127+
Bio = DataGenerator.BojackTheme
128+
};
129+
var bojackAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
130+
var createBookArgs = new QuerySql.CreateBookArgs
131+
{
132+
Name = DataGenerator.BojackBookTitle,
133+
AuthorId = bojackAuthorId
134+
};
135+
await QuerySql.CreateBook(createBookArgs);
136+
createAuthorArgs = new QuerySql.CreateAuthorReturnIdArgs
137+
{
138+
Name = DataGenerator.DrSeussAuthor,
139+
Bio = DataGenerator.DrSeussQuote
140+
};
141+
var drSeussAuthorId = await QuerySql.CreateAuthorReturnId(createAuthorArgs);
142+
createBookArgs = new QuerySql.CreateBookArgs
143+
{
144+
Name = DataGenerator.DrSeussBookTitle,
145+
AuthorId = drSeussAuthorId
146+
};
147+
await QuerySql.CreateBook(createBookArgs);
148+
var expected = new List<QuerySql.ListAllAuthorsBooksRow>()
149+
{
150+
new QuerySql.ListAllAuthorsBooksRow
151+
{
152+
Author = new Author
153+
{
154+
Name = DataGenerator.BojackAuthor,
155+
Bio = DataGenerator.BojackTheme,
156+
},
157+
Book = new Book
158+
{
159+
Name = DataGenerator.BojackBookTitle,
160+
}
161+
},
162+
new QuerySql.ListAllAuthorsBooksRow
163+
{
164+
Author = new Author
165+
{
166+
Name = DataGenerator.DrSeussAuthor,
167+
Bio = DataGenerator.DrSeussQuote,
168+
},
169+
Book = new Book
170+
{
171+
Name = DataGenerator.DrSeussBookTitle,
172+
}
173+
}
174+
};
175+
var actual = await QuerySql.ListAllAuthorsBooks();
176+
Assert.That(SequenceEquals(expected, actual));
177+
}
178+
179+
private static bool Equals(QuerySql.ListAllAuthorsBooksRow x, QuerySql.ListAllAuthorsBooksRow y)
180+
{
181+
return x.Author.Name.Equals(y.Author.Name) && x.Author.Bio.Equals(y.Author.Bio) && x.Book.Name.Equals(y.Book.Name);
182+
}
183+
184+
private static bool SequenceEquals(List<QuerySql.ListAllAuthorsBooksRow> x, List<QuerySql.ListAllAuthorsBooksRow> y)
185+
{
186+
if (x.Count != y.Count)
187+
return false;
188+
x = x.OrderBy<QuerySql.ListAllAuthorsBooksRow, object>(o => o.Author.Name + o.Book.Name).ToList();
189+
y = y.OrderBy<QuerySql.ListAllAuthorsBooksRow, object>(o => o.Author.Name + o.Book.Name).ToList();
190+
return !x.Where((t, i) => !Equals(t, y[i])).Any();
191+
}
192+
193+
[Test]
194+
public async Task TestSelfJoinEmbed()
195+
{
196+
var createAuthorArgs = new QuerySql.CreateAuthorArgs
197+
{
198+
Name = DataGenerator.BojackAuthor,
199+
Bio = DataGenerator.BojackTheme
200+
};
201+
await QuerySql.CreateAuthor(createAuthorArgs);
202+
await QuerySql.CreateAuthor(createAuthorArgs);
203+
var expected = new List<QuerySql.GetDuplicateAuthorsRow>()
204+
{
205+
new QuerySql.GetDuplicateAuthorsRow
206+
{
207+
Author = new Author
208+
{
209+
Name = DataGenerator.BojackAuthor,
210+
Bio = DataGenerator.BojackTheme
211+
},
212+
Author2 = new Author
213+
{
214+
Name = DataGenerator.BojackAuthor,
215+
Bio = DataGenerator.BojackTheme
216+
}
217+
}
218+
};
219+
var actual = await QuerySql.GetDuplicateAuthors();
220+
Assert.That(SequenceEquals(expected, actual));
221+
Assert.That(actual[0].Author.Id, Is.Not.EqualTo(actual[0].Author2.Id));
222+
}
223+
224+
private static bool Equals(QuerySql.GetDuplicateAuthorsRow x, QuerySql.GetDuplicateAuthorsRow y)
225+
{
226+
return x.Author.Name.Equals(y.Author.Name) && x.Author.Bio.Equals(y.Author.Bio) && x.Author2.Name.Equals(y.Author2.Name) && x.Author2.Bio.Equals(y.Author2.Bio);
227+
}
228+
229+
private static bool SequenceEquals(List<QuerySql.GetDuplicateAuthorsRow> x, List<QuerySql.GetDuplicateAuthorsRow> y)
230+
{
231+
if (x.Count != y.Count)
232+
return false;
233+
x = x.OrderBy<QuerySql.GetDuplicateAuthorsRow, object>(o => o.Author.Name + o.Author2.Name).ToList();
234+
y = y.OrderBy<QuerySql.GetDuplicateAuthorsRow, object>(o => o.Author.Name + o.Author2.Name).ToList();
235+
return !x.Where((t, i) => !Equals(t, y[i])).Any();
236+
}
237+
121238
[Test]
122239
public async Task TestSliceIds()
123240
{

0 commit comments

Comments
 (0)