From d7a4c587b7b288a407828eb6872005ff18e490c7 Mon Sep 17 00:00:00 2001 From: Ahmad Moussawi Date: Fri, 9 Sep 2022 06:26:35 +0300 Subject: [PATCH] Handle NULL reference error on clone --- QueryBuilder.Tests/ExecutionTests.cs | 9 ++++ QueryBuilder.Tests/MySqlExecutionTest.cs | 65 ++++++++++++++++++++++++ SqlKata.Execution/Query.Extensions.cs | 11 +++- SqlKata.Execution/XQuery.cs | 8 ++- 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/QueryBuilder.Tests/ExecutionTests.cs b/QueryBuilder.Tests/ExecutionTests.cs index de3c0d43..5d41e7fd 100644 --- a/QueryBuilder.Tests/ExecutionTests.cs +++ b/QueryBuilder.Tests/ExecutionTests.cs @@ -23,5 +23,14 @@ public void TimeoutShouldBeCarriedToNewCreatedFactory() var newFactory = QueryExtensions.CreateQueryFactory(db.Query()); Assert.Equal(db.QueryTimeout, newFactory.QueryTimeout); } + + [Fact(Skip = "timeout over cloned xQuery is not supported yet")] + public void TimeoutShouldBeCarriedToNewCreatedFactoryAfterClone() + { + var db = new QueryFactory(); + db.QueryTimeout = 4000; + var newFactory = QueryExtensions.CreateQueryFactory(db.Query().Clone()); + Assert.Equal(db.QueryTimeout, newFactory.QueryTimeout); + } } } diff --git a/QueryBuilder.Tests/MySqlExecutionTest.cs b/QueryBuilder.Tests/MySqlExecutionTest.cs index d374fdc0..23074157 100644 --- a/QueryBuilder.Tests/MySqlExecutionTest.cs +++ b/QueryBuilder.Tests/MySqlExecutionTest.cs @@ -54,6 +54,71 @@ Color TEXT NULL db.Statement("DROP TABLE IF EXISTS `Cars`"); } + + [Fact] + public void Count() + { + var db = SetupDb(); + var sql = @" + CREATE TABLE Cars( + Id INT PRIMARY KEY AUTO_INCREMENT, + Brand TEXT NOT NULL, + Year INT NOT NULL, + Color TEXT NULL + ) + "; + db.Statement(sql); + + db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Honda', 2020)"); + var count = db.Query("Cars").Count(); + Assert.Equal(1, count); + + db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Toyota', 2021)"); + count = db.Query("Cars").Count(); + Assert.Equal(2, count); + + int affected = db.Query("Cars").Delete(); + Assert.Equal(2, affected); + + count = db.Query("Cars").Count(); + Assert.Equal(0, count); + + db.Statement("DROP TABLE IF EXISTS `Cars`"); + } + + [Fact] + public void CloneThenCount() + { + var db = SetupDb(); + var sql = @" + CREATE TABLE Cars( + Id INT PRIMARY KEY AUTO_INCREMENT, + Brand TEXT NOT NULL, + Year INT NOT NULL, + Color TEXT NULL + ) + "; + db.Statement(sql); + + for (int i = 0; i < 10; i++) + { + db.Query("Cars").Insert(new + { + Brand = "Brand " + i, + Year = "2020", + }); + } + + var query = db.Query("Cars").Where("Id", "<", 5); + var count = query.Count(); + var cloneCount = query.Clone().Count(); + + Assert.Equal(4, count); + Assert.Equal(4, cloneCount); + + db.Statement("DROP TABLE IF EXISTS `Cars`"); + } + public QueryFactory SetupDb() { var host = System.Environment.GetEnvironmentVariable("SQLKATA_MYSQL_HOST"); diff --git a/SqlKata.Execution/Query.Extensions.cs b/SqlKata.Execution/Query.Extensions.cs index af0af252..4a19d608 100644 --- a/SqlKata.Execution/Query.Extensions.cs +++ b/SqlKata.Execution/Query.Extensions.cs @@ -366,7 +366,16 @@ internal static XQuery CastToXQuery(Query query, string method = null) internal static QueryFactory CreateQueryFactory(XQuery xQuery) { - var factory = new QueryFactory(xQuery.Connection, xQuery.Compiler, xQuery.QueryFactory.QueryTimeout); + QueryFactory factory; + + if (xQuery.QueryFactory != null) + { + factory = new QueryFactory(xQuery.Connection, xQuery.Compiler, xQuery.QueryFactory.QueryTimeout); + } + else + { + factory = new QueryFactory(xQuery.Connection, xQuery.Compiler); + } factory.Logger = xQuery.Logger; diff --git a/SqlKata.Execution/XQuery.cs b/SqlKata.Execution/XQuery.cs index b9265fd9..3cb5f14f 100644 --- a/SqlKata.Execution/XQuery.cs +++ b/SqlKata.Execution/XQuery.cs @@ -14,6 +14,7 @@ public class XQuery : Query public XQuery(IDbConnection connection, Compiler compiler) { + this.QueryFactory = new QueryFactory(connection, compiler); this.Connection = connection; this.Compiler = compiler; } @@ -21,7 +22,12 @@ public XQuery(IDbConnection connection, Compiler compiler) public override Query Clone() { - var query = new XQuery(this.Connection, this.Compiler); + var query = new XQuery(this.QueryFactory.Connection, this.QueryFactory.Compiler); + + if (this.QueryFactory?.QueryTimeout != null) + { + query.QueryFactory.QueryTimeout = this.QueryFactory?.QueryTimeout ?? 30; + } query.Clauses = this.Clauses.Select(x => x.Clone()).ToList(); query.Logger = this.Logger;