Skip to content

Commit

Permalink
Change delete syntax to only support 'From' / 'Using' syntax (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
EndsOfTheEarth authored Jun 24, 2023
1 parent 4b003a6 commit c598113
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 293 deletions.
19 changes: 5 additions & 14 deletions Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
- [Update Query](#update-query)
- [Update From Query](#update-from-query)
- [Delete Query](#delete-query)
- [Delete Join Query (MSSQL Only)](#delete-join-query)
- [Delete Using Query (PostgreSql Only)](#delete-using-query)
- [Delete From Query](#delete-from-query)
- [Truncate Query](#truncate-query)
- [Supported Operators](#supported-operators)
- [String Like Condition](#string-like-condition)
Expand Down Expand Up @@ -550,11 +549,9 @@ using(Transaction transaction = new Transaction(DB.Northwind)) {
}
```

## Delete Join Query
## Delete From Query

**Please Note: Join syntax is only supported by Sql Server. An exception will be thrown if this is executed on a PostgreSql database.**

The equivalent syntax for PostgreSql is the 'Delete Using' syntax.
Note: The `From` and `Using` methods are equivalent syntax for both PostgreSql and Sql Server.

```C#
using(Transaction transaction = new Transaction(DB.Northwind)) {
Expand All @@ -564,20 +561,14 @@ using(Transaction transaction = new Transaction(DB.Northwind)) {

NonQueryResult result = Query
.Delete(orderTable)
.Join(customersTable).On(orderTable.CustomerID == customersTable.CustomerID)
.Where(customersTable.Region.IsNull)
.From(customersTable)
.Where(orderTable.CustomerID == customersTable.CustomerID & customersTable.Region.IsNull)
.Execute(transaction);

transaction.Commit();
}
```

## Delete Using Query

**Please Note: Delete using syntax is only supported by PostgreSql. An exception will be thrown if this is executed on an Sql Server database.**

The equivalent syntax for Sql Server is the 'Delete Join' syntax.

```C#
using(Transaction transaction = new Transaction(DB.Northwind)) {

Expand Down
19 changes: 11 additions & 8 deletions QueryLite/Databases/PostgreSql/DeleteQueryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ internal sealed class PostgreSqlDeleteQueryGenerator : IDeleteQueryGenerator {

string IDeleteQueryGenerator.GetSql<RESULT>(DeleteQueryTemplate template, IDatabase database, IParametersBuilder? parameters, Func<IResultRow, RESULT>? outputFunc) {

if(template.Joins != null) {
throw new Exception("Delete join syntax is not supported by PostgreSql");
}

StringBuilder sql = StringBuilderCache.Acquire();

sql.Append("DELETE FROM ");
Expand All @@ -49,18 +45,25 @@ string IDeleteQueryGenerator.GetSql<RESULT>(DeleteQueryTemplate template, IDatab
SqlHelper.AppendEncloseTableName(sql, template.Table);
sql.Append(" AS ").Append(template.Table.Alias);

bool useAliases = template.Usings != null;
bool useAliases = template.FromTables != null;

if(template.Usings != null && template.Usings.Count > 0) {
if(template.FromTables != null) {

sql.Append(" USING ");

for(int index = 0; index < template.Usings.Count; index++) {
for(int index = 0; index < template.FromTables.Count; index++) {

if(index > 0) {
sql.Append(',');
}
ITable usingTable = template.Usings[index];
ITable usingTable = template.FromTables[index];

string usingTableSchemaName = database.SchemaMap(template.Table.SchemaName);

if(!string.IsNullOrWhiteSpace(usingTableSchemaName)) {
SqlHelper.AppendEncloseSchemaName(sql, usingTableSchemaName);
sql.Append('.');
}

SqlHelper.AppendEncloseTableName(sql, usingTable);

Expand Down
19 changes: 11 additions & 8 deletions QueryLite/Databases/PostgreSql/PreparedDeleteQueryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ internal sealed class PostgreSqlPreparedDeleteQueryGenerator : IPreparedDeleteQu

string IPreparedDeleteQueryGenerator.GetSql<PARAMETERS, RESULT>(PreparedDeleteQueryTemplate<PARAMETERS> template, IDatabase database, out PreparedParameterList<PARAMETERS> parameters, Func<IResultRow, RESULT>? outputFunc) {

if(template.Joins != null) {
throw new Exception("Delete join syntax is not supported by PostgreSql");
}

parameters = new PreparedParameterList<PARAMETERS>();

StringBuilder sql = StringBuilderCache.Acquire();
Expand All @@ -51,18 +47,25 @@ string IPreparedDeleteQueryGenerator.GetSql<PARAMETERS, RESULT>(PreparedDeleteQu
SqlHelper.AppendEncloseTableName(sql, template.Table);
sql.Append(" AS ").Append(template.Table.Alias);

bool useAliases = template.Usings != null;
bool useAliases = template.FromTables != null;

if(template.Usings != null && template.Usings.Count > 0) {
if(template.FromTables != null) {

sql.Append(" USING ");

for(int index = 0; index < template.Usings.Count; index++) {
for(int index = 0; index < template.FromTables.Count; index++) {

if(index > 0) {
sql.Append(',');
}
ITable usingTable = template.Usings[index];
ITable usingTable = template.FromTables[index];

string usingTableSchemaName = database.SchemaMap(template.Table.SchemaName);

if(!string.IsNullOrWhiteSpace(usingTableSchemaName)) {
SqlHelper.AppendEncloseSchemaName(sql, usingTableSchemaName);
sql.Append('.');
}

SqlHelper.AppendEncloseTableName(sql, usingTable);

Expand Down
50 changes: 24 additions & 26 deletions QueryLite/Databases/SqlServer/DeleteQueryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,21 @@ internal sealed class SqlServerDeleteQueryGenerator : IDeleteQueryGenerator {

string IDeleteQueryGenerator.GetSql<RESULT>(DeleteQueryTemplate template, IDatabase database, IParametersBuilder? parameters, Func<IResultRow, RESULT>? outputFunc) {

if(template.Usings != null) {
throw new Exception("Using syntax is not supported by Sql Server");
}

StringBuilder sql = StringBuilderCache.Acquire(capacity: 256);

bool useAlias = template.Joins?.Count != 0;

//
// Note: The OUPUT clause changes goes before the 'FROM' clause when using aliasing and after the 'FROM' clause when not
//
if(useAlias) {
if(template.FromTables != null) {

sql.Append("DELETE ").Append(template.Table.Alias);
sql.Append("DELETE FROM ").Append(template.Table.Alias);

GenerateOutputClause(sql, outputFunc);
}
else {

sql.Append(" FROM ");
sql.Append("DELETE FROM ");

string schemaName = database.SchemaMap(template.Table.SchemaName);

Expand All @@ -58,11 +55,14 @@ string IDeleteQueryGenerator.GetSql<RESULT>(DeleteQueryTemplate template, IDatab
}
SqlHelper.AppendEncloseTableName(sql, template.Table);

sql.Append(" AS ").Append(template.Table.Alias).Append(' ');
GenerateOutputClause(sql, outputFunc);
}
else {

sql.Append("DELETE FROM ");
bool useAlias = template.FromTables != null;

if(template.FromTables != null) {

sql.Append(" FROM ");

string schemaName = database.SchemaMap(template.Table.SchemaName);

Expand All @@ -72,28 +72,26 @@ string IDeleteQueryGenerator.GetSql<RESULT>(DeleteQueryTemplate template, IDatab
}
SqlHelper.AppendEncloseTableName(sql, template.Table);

GenerateOutputClause(sql, outputFunc);
}
sql.Append(" AS ").Append(template.Table.Alias).Append(' ');

if(template.Joins != null) {
for(int index = 0; index < template.FromTables.Count; index++) {

foreach(IJoin join in template.Joins) {
sql.Append(',');

sql.Append(join.JoinType switch {
JoinType.Join => " JOIN ",
JoinType.LeftJoin => " LEFT JOIN ",
_ => throw new Exception($"Unknown join type. Type = {join.JoinType}")
});
ITable usingTable = template.FromTables[index];

string joinSchemaName = database.SchemaMap(join.Table.SchemaName);
string usingTableSchemaName = database.SchemaMap(template.Table.SchemaName);

if(!string.IsNullOrWhiteSpace(joinSchemaName)) {
SqlHelper.AppendEncloseSchemaName(sql, joinSchemaName);
if(!string.IsNullOrWhiteSpace(usingTableSchemaName)) {
SqlHelper.AppendEncloseSchemaName(sql, usingTableSchemaName);
sql.Append('.');
}
SqlHelper.AppendEncloseTableName(sql, join.Table);
sql.Append(" AS ").Append(join.Table.Alias).Append(" ON ");
join.Condition.GetSql(sql, database, useAlias: true, parameters);

SqlHelper.AppendEncloseTableName(sql, usingTable);

sql.Append(' ');

SqlHelper.AppendEncloseAlias(sql, usingTable.Alias);
}
}

Expand Down
53 changes: 24 additions & 29 deletions QueryLite/Databases/SqlServer/PreparedDeleteQueryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,22 @@ internal sealed class PreparedDeleteQueryGenerator : IPreparedDeleteQueryGenerat

string IPreparedDeleteQueryGenerator.GetSql<PARAMETERS, RESULT>(PreparedDeleteQueryTemplate<PARAMETERS> template, IDatabase database, out PreparedParameterList<PARAMETERS> parameters, Func<IResultRow, RESULT>? outputFunc) {

if(template.Usings != null) {
throw new Exception("Using syntax is not supported by Sql Server");
}

parameters = new PreparedParameterList<PARAMETERS>();

StringBuilder sql = StringBuilderCache.Acquire(capacity: 256);

bool useAlias = template.Joins?.Count != 0;

//
// Note: The OUPUT clause changes goes before the 'FROM' clause when using aliasing and after the 'FROM' clause when not
//
if(useAlias) {
if(template.FromTables != null) {

sql.Append("DELETE ").Append(template.Table.Alias);
sql.Append("DELETE FROM ").Append(template.Table.Alias);

GenerateOutputClause(sql, outputFunc);
}
else {

sql.Append(" FROM ");
sql.Append("DELETE FROM ");

string schemaName = database.SchemaMap(template.Table.SchemaName);

Expand All @@ -60,11 +56,14 @@ string IPreparedDeleteQueryGenerator.GetSql<PARAMETERS, RESULT>(PreparedDeleteQu
}
SqlHelper.AppendEncloseTableName(sql, template.Table);

sql.Append(" AS ").Append(template.Table.Alias).Append(' ');
GenerateOutputClause(sql, outputFunc);
}
else {

sql.Append("DELETE FROM ");
bool useAlias = template.FromTables != null;

if(template.FromTables != null) {

sql.Append(" FROM ");

string schemaName = database.SchemaMap(template.Table.SchemaName);

Expand All @@ -74,30 +73,26 @@ string IPreparedDeleteQueryGenerator.GetSql<PARAMETERS, RESULT>(PreparedDeleteQu
}
SqlHelper.AppendEncloseTableName(sql, template.Table);

GenerateOutputClause(sql, outputFunc);
}

if(template.Joins != null) {
sql.Append(" AS ").Append(template.Table.Alias).Append(' ');

for(int index = 0; index < template.Joins.Count; index++) {
for(int index = 0; index < template.FromTables.Count; index++) {

PreparedDeleteJoin<PARAMETERS> join = template.Joins[index];
sql.Append(',');

sql.Append(join.JoinType switch {
JoinType.Join => " JOIN ",
JoinType.LeftJoin => " LEFT JOIN ",
_ => throw new Exception($"Unknown join type. Type = {join.JoinType}")
});
ITable usingTable = template.FromTables[index];

string joinSchemaName = database.SchemaMap(join.Table.SchemaName);
string usingTableSchemaName = database.SchemaMap(template.Table.SchemaName);

if(!string.IsNullOrWhiteSpace(joinSchemaName)) {
SqlHelper.AppendEncloseSchemaName(sql, joinSchemaName);
if(!string.IsNullOrWhiteSpace(usingTableSchemaName)) {
SqlHelper.AppendEncloseSchemaName(sql, usingTableSchemaName);
sql.Append('.');
}
SqlHelper.AppendEncloseTableName(sql, join.Table);
sql.Append(" AS ").Append(join.Table.Alias).Append(" ON ");
join.Condition.GetSql(sql, database, parameters, useAlias: true);

SqlHelper.AppendEncloseTableName(sql, usingTable);

sql.Append(' ');

SqlHelper.AppendEncloseAlias(sql, usingTable.Alias);
}
}

Expand Down
Loading

0 comments on commit c598113

Please sign in to comment.