Skip to content

Commit c860a3d

Browse files
allow raw expressions on Insert/Update/Delete operations
1 parent f083ed5 commit c860a3d

3 files changed

Lines changed: 122 additions & 12 deletions

File tree

QueryBuilder.Tests/InsertTests.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ public void InsertWithEmptyString()
118118
[Fact]
119119
public void InsertWithByteArray()
120120
{
121-
var fauxImagebytes = new byte[] {0x1, 0x3, 0x3, 0x7};
121+
var fauxImagebytes = new byte[] { 0x1, 0x3, 0x3, 0x7 };
122122
var query = new Query("Books")
123-
.AsInsert(new[]{"Id", "CoverImageBytes"},
123+
.AsInsert(new[] { "Id", "CoverImageBytes" },
124124
new object[]
125125
{
126126
1,
@@ -169,5 +169,40 @@ public void InsertWithIgnoreAndColumnProperties()
169169
c[EngineCodes.Firebird]);
170170
}
171171

172+
[Fact]
173+
public void InsertFromRaw()
174+
{
175+
var query = new Query().FromRaw("Table.With.Dots").AsInsert(new
176+
{
177+
Name = "The User",
178+
Age = new DateTime(2018, 1, 1),
179+
});
180+
181+
var c = Compile(query);
182+
183+
Assert.Equal(
184+
"INSERT INTO Table.With.Dots ([Name], [Age]) VALUES ('The User', '2018-01-01')",
185+
c[EngineCodes.SqlServer]
186+
);
187+
188+
}
189+
190+
191+
[Fact]
192+
public void InsertFromQueryShouldFail()
193+
{
194+
var query = new Query().From(new Query("InnerTable")).AsInsert(new
195+
{
196+
Name = "The User",
197+
Age = new DateTime(2018, 1, 1),
198+
});
199+
200+
Assert.Throws<InvalidOperationException>(() =>
201+
{
202+
Compile(query);
203+
});
204+
205+
}
206+
172207
}
173208
}

QueryBuilder.Tests/UpdateTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,38 @@ public void UpdateWithKeyAttribute()
161161
c[EngineCodes.Firebird]);
162162
}
163163

164+
165+
[Fact]
166+
public void UpdateFromRaw()
167+
{
168+
var query = new Query().FromRaw("Table.With.Dots").AsUpdate(new
169+
{
170+
Name = "The User",
171+
});
172+
173+
var c = Compile(query);
174+
175+
Assert.Equal(
176+
"UPDATE Table.With.Dots SET [Name] = 'The User'",
177+
c[EngineCodes.SqlServer]
178+
);
179+
}
180+
181+
182+
[Fact]
183+
public void UpdateFromQueryShouldFail()
184+
{
185+
var query = new Query().From(new Query("InnerTable")).AsUpdate(new
186+
{
187+
Name = "The User",
188+
});
189+
190+
Assert.Throws<InvalidOperationException>(() =>
191+
{
192+
Compile(query);
193+
});
194+
195+
}
196+
164197
}
165198
}

QueryBuilder/Compilers/Compiler.cs

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,22 @@ private SqlResult CompileDeleteQuery(Query query)
221221
throw new InvalidOperationException("No table set to delete");
222222
}
223223

224-
var from = ctx.Query.GetOneComponent<AbstractFrom>("from", EngineCode);
224+
var fromClause = ctx.Query.GetOneComponent<AbstractFrom>("from", EngineCode);
225+
226+
string table = null;
227+
228+
if (fromClause is FromClause fromClauseCast)
229+
{
230+
table = Wrap(fromClauseCast.Table);
231+
}
232+
233+
if (fromClause is RawFromClause rawFromClause)
234+
{
235+
table = WrapIdentifiers(rawFromClause.Expression);
236+
ctx.Bindings.AddRange(rawFromClause.Bindings);
237+
}
225238

226-
if (!(from is FromClause))
239+
if (table is null)
227240
{
228241
throw new InvalidOperationException("Invalid table expression");
229242
}
@@ -235,7 +248,7 @@ private SqlResult CompileDeleteQuery(Query query)
235248
where = " " + where;
236249
}
237250

238-
ctx.RawSql = "DELETE FROM " + CompileTableExpression(ctx, from) + where;
251+
ctx.RawSql = $"DELETE FROM {table}{where}";
239252

240253
return ctx;
241254
}
@@ -252,9 +265,22 @@ private SqlResult CompileUpdateQuery(Query query)
252265
throw new InvalidOperationException("No table set to update");
253266
}
254267

255-
var from = ctx.Query.GetOneComponent<AbstractFrom>("from", EngineCode);
268+
var fromClause = ctx.Query.GetOneComponent<AbstractFrom>("from", EngineCode);
256269

257-
if (!(from is FromClause))
270+
string table = null;
271+
272+
if (fromClause is FromClause fromClauseCast)
273+
{
274+
table = Wrap(fromClauseCast.Table);
275+
}
276+
277+
if (fromClause is RawFromClause rawFromClause)
278+
{
279+
table = WrapIdentifiers(rawFromClause.Expression);
280+
ctx.Bindings.AddRange(rawFromClause.Bindings);
281+
}
282+
283+
if (table is null)
258284
{
259285
throw new InvalidOperationException("Invalid table expression");
260286
}
@@ -277,9 +303,9 @@ private SqlResult CompileUpdateQuery(Query query)
277303
where = " " + where;
278304
}
279305

280-
ctx.RawSql = "UPDATE " + CompileTableExpression(ctx, from)
281-
+ " SET " + string.Join(", ", parts)
282-
+ where;
306+
var sets = string.Join(", ", parts);
307+
308+
ctx.RawSql = $"UPDATE {table} SET {sets}{where}";
283309

284310
return ctx;
285311
}
@@ -296,14 +322,30 @@ protected virtual SqlResult CompileInsertQuery(Query query)
296322
throw new InvalidOperationException("No table set to insert");
297323
}
298324

299-
var fromClause = ctx.Query.GetOneComponent<FromClause>("from", EngineCode);
325+
var fromClause = ctx.Query.GetOneComponent<AbstractFrom>("from", EngineCode);
300326

301327
if (fromClause is null)
302328
{
303329
throw new InvalidOperationException("Invalid table expression");
304330
}
305331

306-
var table = Wrap(fromClause.Table);
332+
string table = null;
333+
334+
if (fromClause is FromClause fromClauseCast)
335+
{
336+
table = Wrap(fromClauseCast.Table);
337+
}
338+
339+
if (fromClause is RawFromClause rawFromClause)
340+
{
341+
table = WrapIdentifiers(rawFromClause.Expression);
342+
ctx.Bindings.AddRange(rawFromClause.Bindings);
343+
}
344+
345+
if (table is null)
346+
{
347+
throw new InvalidOperationException("Invalid table expression");
348+
}
307349

308350
var inserts = ctx.Query.GetComponents<AbstractInsertClause>("insert", EngineCode);
309351

0 commit comments

Comments
 (0)