Skip to content

Commit

Permalink
Merge branch 'master' of github.com:sqlkata/querybuilder into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmad-moussawi committed Jun 11, 2021
2 parents f6a9e19 + b762ed9 commit f2c706a
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 7 deletions.
34 changes: 34 additions & 0 deletions QueryBuilder.Tests/GeneralTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,5 +401,39 @@ public void Where_Nested()

Assert.Equal("SELECT * FROM [table] WHERE ([a] = 1 OR [a] = 2)", c[EngineCodes.SqlServer].ToString());
}

[Fact]
public void UnsafeLiteral_Insert()
{
var query = new Query("Table").AsInsert(new
{
Count = new UnsafeLiteral("Count + 1")
});

var engines = new[] {
EngineCodes.SqlServer,
};

var c = Compilers.Compile(engines, query);

Assert.Equal("INSERT INTO [Table] ([Count]) VALUES (Count + 1)", c[EngineCodes.SqlServer].ToString());
}

[Fact]
public void UnsafeLiteral_Update()
{
var query = new Query("Table").AsUpdate(new
{
Count = new UnsafeLiteral("Count + 1")
});

var engines = new[] {
EngineCodes.SqlServer,
};

var c = Compilers.Compile(engines, query);

Assert.Equal("UPDATE [Table] SET [Count] = Count + 1", c[EngineCodes.SqlServer].ToString());
}
}
}
32 changes: 32 additions & 0 deletions QueryBuilder.Tests/UpdateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,37 @@ public void UpdateUsingExpandoObject()
"UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'",
c[EngineCodes.SqlServer]);
}

[Fact]
public void IncrementUpdate()
{
var query = new Query("Table").AsIncrement("Total");
var c = Compile(query);
Assert.Equal("UPDATE [Table] SET [Total] = [Total] + 1", c[EngineCodes.SqlServer]);
}

[Fact]
public void IncrementUpdateWithValue()
{
var query = new Query("Table").AsIncrement("Total", 2);
var c = Compile(query);
Assert.Equal("UPDATE [Table] SET [Total] = [Total] + 2", c[EngineCodes.SqlServer]);
}

[Fact]
public void IncrementUpdateWithWheres()
{
var query = new Query("Table").Where("Name", "A").AsIncrement("Total", 2);
var c = Compile(query);
Assert.Equal("UPDATE [Table] SET [Total] = [Total] + 2 WHERE [Name] = 'A'", c[EngineCodes.SqlServer]);
}

[Fact]
public void DecrementUpdate()
{
var query = new Query("Table").Where("Name", "A").AsDecrement("Total", 2);
var c = Compile(query);
Assert.Equal("UPDATE [Table] SET [Total] = [Total] - 2 WHERE [Name] = 'A'", c[EngineCodes.SqlServer]);
}
}
}
19 changes: 19 additions & 0 deletions QueryBuilder/Clauses/IncrementClause.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace SqlKata
{
public class IncrementClause : InsertClause
{
public string Column { get; set; }
public int Value { get; set; } = 1;

public override AbstractClause Clone()
{
return new IncrementClause
{
Engine = Engine,
Component = Component,
Column = Column,
Value = Value
};
}
}
}
37 changes: 30 additions & 7 deletions QueryBuilder/Compilers/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,25 +285,48 @@ protected virtual SqlResult CompileUpdateQuery(Query query)
throw new InvalidOperationException("Invalid table expression");
}

var toUpdate = ctx.Query.GetOneComponent<InsertClause>("update", EngineCode);
// check for increment statements
var clause = ctx.Query.GetOneComponent("update", EngineCode);

string wheres;

if (clause != null && clause is IncrementClause increment)
{
var column = Wrap(increment.Column);
var value = Parameter(ctx, Math.Abs(increment.Value));
var sign = increment.Value >= 0 ? "+" : "-";

wheres = CompileWheres(ctx);

if (!string.IsNullOrEmpty(wheres))
{
wheres = " " + wheres;
}

ctx.RawSql = $"UPDATE {table} SET {column} = {column} {sign} {value}{wheres}";

return ctx;
}


var toUpdate = ctx.Query.GetOneComponent<InsertClause>("update", EngineCode);
var parts = new List<string>();

for (var i = 0; i < toUpdate.Columns.Count; i++)
{
parts.Add(Wrap(toUpdate.Columns[i]) + " = " + Parameter(ctx, toUpdate.Values[i]));
}

var where = CompileWheres(ctx);
var sets = string.Join(", ", parts);

if (!string.IsNullOrEmpty(where))
wheres = CompileWheres(ctx);

if (!string.IsNullOrEmpty(wheres))
{
where = " " + where;
wheres = " " + wheres;
}

var sets = string.Join(", ", parts);

ctx.RawSql = $"UPDATE {table} SET {sets}{where}";
ctx.RawSql = $"UPDATE {table} SET {sets}{wheres}";

return ctx;
}
Expand Down
17 changes: 17 additions & 0 deletions QueryBuilder/Query.Update.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,22 @@ public Query AsUpdate(IEnumerable<KeyValuePair<string, object>> values)

return this;
}

public Query AsIncrement(string column, int value = 1)
{
Method = "update";
AddOrReplaceComponent("update", new IncrementClause
{
Column = column,
Value = value
});

return this;
}

public Query AsDecrement(string column, int value = 1)
{
return AsIncrement(column, -value);
}
}
}
20 changes: 20 additions & 0 deletions SqlKata.Execution/Query.Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,26 @@ public static async Task<int> UpdateAsync(this Query query, object data, IDbTran
return await CreateQueryFactory(query).ExecuteAsync(query.AsUpdate(data), transaction, timeout, cancellationToken);
}

public static int Increment(this Query query, string column, int value = 1, IDbTransaction transaction = null, int? timeout = null)
{
return CreateQueryFactory(query).Execute(query.AsIncrement(column, value), transaction, timeout);
}

public static async Task<int> IncrementAsync(this Query query, string column, int value = 1, IDbTransaction transaction = null, int? timeout = null, CancellationToken cancellationToken = default)
{
return await CreateQueryFactory(query).ExecuteAsync(query.AsIncrement(column, value), transaction, timeout, cancellationToken);
}

public static int Decrement(this Query query, string column, int value = 1, IDbTransaction transaction = null, int? timeout = null)
{
return CreateQueryFactory(query).Execute(query.AsDecrement(column, value), transaction, timeout);
}

public static async Task<int> DecrementAsync(this Query query, string column, int value = 1, IDbTransaction transaction = null, int? timeout = null, CancellationToken cancellationToken = default)
{
return await CreateQueryFactory(query).ExecuteAsync(query.AsDecrement(column, value), transaction, timeout, cancellationToken);
}

public static int Delete(this Query query, IDbTransaction transaction = null, int? timeout = null)
{
return CreateQueryFactory(query).Execute(query.AsDelete(), transaction, timeout);
Expand Down

0 comments on commit f2c706a

Please sign in to comment.