From ff45bf36d166f199dc411d653e9de9656d3f9499 Mon Sep 17 00:00:00 2001 From: Miha Jakovac Date: Tue, 24 Nov 2020 15:00:01 +0100 Subject: [PATCH 1/2] Readme and interfaces from Core library * moved interfaces to core library * readme file updated, small test fix --- README.md | 69 ++++++++++++++++++- .../MySqlTestGeneratorTests.cs | 4 +- .../PostgresqlTestGeneratorTests.cs | 4 +- .../SqlServerTestGeneratorTests.cs | 4 +- .../RelationalDatabaseTestGenerator.cs | 2 +- .../Interfaces/IDatabaseTestGenerator.cs | 17 ----- .../Interfaces/IDatabaseTestRunner.cs | 18 ----- .../QAToolKit.Engine.Database.csproj | 2 +- .../Runners/RelationalDatabaseTestRunner.cs | 2 +- 9 files changed, 77 insertions(+), 45 deletions(-) delete mode 100644 src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestGenerator.cs delete mode 100644 src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestRunner.cs diff --git a/README.md b/README.md index ce37ff0..903fa5a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,74 @@ [![Sonarcloud Quality gate](https://github.com/qatoolkit/qatoolkit-engine-database-net/workflows/Sonarqube%20Analyze/badge.svg)](https://sonarcloud.io/dashboard?id=qatoolkit_qatoolkit-engine-database-net) [![NuGet package](https://img.shields.io/nuget/v/QAToolKit.Engine.DataBase?label=QAToolKit.Engine.Database)](https://www.nuget.org/packages/QAToolKit.Engine.Database/) -**Not ready for release.** +## Description +`QAToolKit.Engine.Database` is a .NET standard library, which can be used to do database fitness tests. For example, if you want to test that table is present in database, or certain number of records exist in specific table or if a record exists. + +`DatabaseTestType` enumeration currently described those three test types: +- `ObjectExits`: Check if table, view or stored procedure exists. +- `RecordCount`: Check if record count in specific table equals an expression. +- `RecordExist`: Check if a record exists in specific table. + +Currently supports only relational databases: `SQLServer`, `MySQL` and `PostgreSQL`. + +## Sample + +```csharp +var generator = new SqlServerTestGenerator(options => +{ + options.AddDatabaseObjectExitsRule(new string[] { "mytable" }, DatabaseObjectType.Table); + + options.AddDatabaseRecordExitsRule( + new List() + { + new DatabaseRule() + { + TableName = "mytable", + PredicateValue = "name = 'myname'" + } + }); + + options.AddDatabaseRecordsCountRule( + new List() + { + new DatabaseRule() + { + TableName = "mytable", + PredicateValue = "=100" + } + }); +}); + +List scripts = await generator.Generate(); +``` +The code above will generate a SQLServer `DatabaseScript` list, which will be used by runner to run the tests against database. + +Above example adds all three test types to the generator: +- `AddDatabaseObjectExitsRule`: will check if a table `mytable` exists in the database. +- `AddDatabaseRecordExitsRule`: will check if a record in table `mytable` with `name` equals `myname` exists. +- `AddDatabaseRecordsCountRule`: will check if there is exactly 100 records in the `mytable` table. + +Alternatively if you want to use `MySQL` or `PostgreSQL` generators, you can use MySqlTestGenerator` or `PostgresqlTestGenerator` respectively. + +To run the tests, we create a `SqlServerTestRunner` runner: + +```csharp +var runner = new SqlServerTestRunner(scripts, options => +{ + options.AddSQLServerConnection("server=localhost;user=sa;password=Mihaj666.;Initial Catalog="); +}); + +List results = await runner.Run(); +``` + +Alternatively if you want to use `MySQL` or `PostgreSQL` runners, you can use MySqlTestRunner` or `PostgresqlTestRunner` respectively. + +Please note that **your user must have correct database permissions**. I suggest a read-only permissions that can also access `sys` or `information_schema` schemas. + +## To-Do + +- Implement asserters for processing the `DatabaseScriptResult` list. +- Add more test types if necessary. ## License diff --git a/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs b/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs index b239130..7a9a84a 100644 --- a/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs +++ b/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs @@ -172,7 +172,7 @@ public async Task MySqlRecordExistScriptTest_Success() new DatabaseRule() { TableName = "mytable", - PredicateValue = "= 'myname'" + PredicateValue = "name = 'myname'" } }); }); @@ -181,7 +181,7 @@ public async Task MySqlRecordExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE = 'myname');", + $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE name = 'myname');", DatabaseTestType.RecordExist, DatabaseKind.MySQL) }.ToExpectedObject(); diff --git a/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs b/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs index f40c72e..69bdfe7 100644 --- a/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs +++ b/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs @@ -172,7 +172,7 @@ public async Task PostgresqlRecordExistScriptTest_Success() new DatabaseRule() { TableName = "mytable", - PredicateValue = "= 'myname'" + PredicateValue = "name = 'myname'" } }); }); @@ -181,7 +181,7 @@ public async Task PostgresqlRecordExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE = 'myname');", + $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE name = 'myname');", DatabaseTestType.RecordExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); diff --git a/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs b/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs index c6cf3ef..4a9f1b9 100644 --- a/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs +++ b/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs @@ -173,7 +173,7 @@ public async Task SqlServerRecordExistScriptTest_Success() new DatabaseRule() { TableName = "mytable", - PredicateValue = "= 'myname'" + PredicateValue = "name = 'myname'" } }); }); @@ -182,7 +182,7 @@ public async Task SqlServerRecordExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"IF EXISTS(SELECT 1 FROM mytable WHERE = 'myname') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS(SELECT 1 FROM mytable WHERE name = 'myname') BEGIN Select 1 END ELSE BEGIN Select 0 END", DatabaseTestType.RecordExist, DatabaseKind.SQLServer) }.ToExpectedObject(); diff --git a/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs b/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs index 6ccaa4b..1f46d2a 100644 --- a/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs +++ b/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs @@ -1,4 +1,4 @@ -using QAToolKit.Engine.Database.Interfaces; +using QAToolKit.Core.Interfaces; using QAToolKit.Engine.Database.Models; using System; using System.Collections.Generic; diff --git a/src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestGenerator.cs b/src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestGenerator.cs deleted file mode 100644 index baf7fee..0000000 --- a/src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestGenerator.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace QAToolKit.Engine.Database.Interfaces -{ - /// - /// Database script generator interface - /// - public interface IDatabaseTestGenerator - { - /// - /// Generate a script - /// - /// - Task> Generate(); - } -} \ No newline at end of file diff --git a/src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestRunner.cs b/src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestRunner.cs deleted file mode 100644 index 79cfac8..0000000 --- a/src/QAToolKit.Engine.Database/Interfaces/IDatabaseTestRunner.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace QAToolKit.Engine.Database.Interfaces -{ - /// - /// Database runner interface - /// - /// - public interface IDatabaseTestRunner - { - /// - /// Run a script - /// - /// - Task> Run(); - } -} \ No newline at end of file diff --git a/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj b/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj index 8be597b..7629a46 100644 --- a/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj +++ b/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj @@ -38,7 +38,7 @@ - + diff --git a/src/QAToolKit.Engine.Database/Runners/RelationalDatabaseTestRunner.cs b/src/QAToolKit.Engine.Database/Runners/RelationalDatabaseTestRunner.cs index 7e5d785..d9d4d80 100644 --- a/src/QAToolKit.Engine.Database/Runners/RelationalDatabaseTestRunner.cs +++ b/src/QAToolKit.Engine.Database/Runners/RelationalDatabaseTestRunner.cs @@ -1,10 +1,10 @@ using Dapper; -using QAToolKit.Engine.Database.Interfaces; using QAToolKit.Engine.Database.Models; using System; using System.Collections.Generic; using System.Data; using System.Threading.Tasks; +using QAToolKit.Core.Interfaces; namespace QAToolKit.Engine.Database.Runners { From 807036516bb709a00d839a9efd3b64d9c4068ee4 Mon Sep 17 00:00:00 2001 From: Miha Jakovac Date: Fri, 27 Nov 2020 09:47:32 +0100 Subject: [PATCH 2/2] New SQL generator * moved interfaces to core library * readme file updated, small test fix * new sql query builder * updated readme --- Directory.Build.props | 2 +- README.md | 23 ++++----- .../MySqlTestGeneratorTests.cs | 39 ++++++++------- .../PostgresqlTestGeneratorTests.cs | 37 +++++++------- .../SqlServerTestGeneratorTests.cs | 37 +++++++------- .../DatabaseTestGeneratorOptions.cs | 12 ++--- .../Generators/MySqlTestGenerator.cs | 49 ++++++++++++++++--- .../Generators/PostgresqlTestGenerator.cs | 40 ++++++++++++--- .../RelationalDatabaseTestGenerator.cs | 4 +- .../Generators/SqlServerTestGenerator.cs | 42 +++++++++++++--- ...baseRule.cs => DatabaseRecordCountRule.cs} | 10 ++-- .../Models/DatabaseRecordExistRule.cs | 25 ++++++++++ .../QAToolKit.Engine.Database.csproj | 1 + 13 files changed, 222 insertions(+), 99 deletions(-) rename src/QAToolKit.Engine.Database/Models/{DatabaseRule.cs => DatabaseRecordCountRule.cs} (57%) create mode 100644 src/QAToolKit.Engine.Database/Models/DatabaseRecordExistRule.cs diff --git a/Directory.Build.props b/Directory.Build.props index c2a8bf4..964bde6 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 0.2.0 + 0.2.5 \ No newline at end of file diff --git a/README.md b/README.md index 903fa5a..fcd6cba 100644 --- a/README.md +++ b/README.md @@ -21,24 +21,25 @@ var generator = new SqlServerTestGenerator(options => { options.AddDatabaseObjectExitsRule(new string[] { "mytable" }, DatabaseObjectType.Table); - options.AddDatabaseRecordExitsRule( - new List() + options.AddDatabaseRecordExitsRule(new List() { - new DatabaseRule() + new DatabaseRecordExistRule() { TableName = "mytable", - PredicateValue = "name = 'myname'" + ColumnName = "name", + Operator = "=", + Value = "myname" } }); - options.AddDatabaseRecordsCountRule( - new List() + options.AddDatabaseRecordsCountRule(new List() { - new DatabaseRule() + new DatabaseRecordCountRule() { - TableName = "mytable", - PredicateValue = "=100" - } + TableName = "mytable", + Count = 100, + Operator = "=" + } }); }); @@ -58,7 +59,7 @@ To run the tests, we create a `SqlServerTestRunner` runner: ```csharp var runner = new SqlServerTestRunner(scripts, options => { - options.AddSQLServerConnection("server=localhost;user=sa;password=Mihaj666.;Initial Catalog="); + options.AddSQLServerConnection("server=localhost;user=user;password=mypassword;Initial Catalog=myDatabase"); }); List results = await runner.Run(); diff --git a/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs b/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs index 7a9a84a..84ab958 100644 --- a/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs +++ b/src/QAToolKit.Engine.Database.Test/MySqlTestGeneratorTests.cs @@ -21,7 +21,7 @@ public async Task MySqlTableExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS(SELECT * FROM information_schema.tables WHERE table_name = 'mytable');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`tables` WHERE `table_name` = 'mytable');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL) }.ToExpectedObject(); @@ -42,7 +42,7 @@ public async Task MySqlViewExistScriptTest_Success() { new DatabaseScript( "myview", - $@"SELECT EXISTS(SELECT * FROM information_schema.views WHERE table_name = 'myview');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`views` WHERE `table_name` = 'myview');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL) }.ToExpectedObject(); @@ -63,7 +63,7 @@ public async Task MySqlStoredProcedureExistScriptTest_Success() { new DatabaseScript( "mystoredprocedure", - $@"SELECT EXISTS(SELECT * FROM information_schema.routines WHERE routine_name = 'mystoredprocedure');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`routines` WHERE `routine_name` = 'mystoredprocedure');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL) }.ToExpectedObject(); @@ -84,12 +84,12 @@ public async Task MySqlMultipleTableExistScriptTest_Success() { new DatabaseScript( "table1", - $@"SELECT EXISTS(SELECT * FROM information_schema.tables WHERE table_name = 'table1');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`tables` WHERE `table_name` = 'table1');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL), new DatabaseScript( "table2", - $@"SELECT EXISTS(SELECT * FROM information_schema.tables WHERE table_name = 'table2');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`tables` WHERE `table_name` = 'table2');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL) }.ToExpectedObject(); @@ -110,12 +110,12 @@ public async Task MySqlMultipleViewExistScriptTest_Success() { new DatabaseScript( "view1", - $@"SELECT EXISTS(SELECT * FROM information_schema.views WHERE table_name = 'view1');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`views` WHERE `table_name` = 'view1');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL), new DatabaseScript( "view2", - $@"SELECT EXISTS(SELECT * FROM information_schema.views WHERE table_name = 'view2');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`views` WHERE `table_name` = 'view2');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL) }.ToExpectedObject(); @@ -136,12 +136,12 @@ public async Task MySqlMultipleStoredProcedureExistScriptTest_Success() { new DatabaseScript( "sp1", - $@"SELECT EXISTS(SELECT * FROM information_schema.routines WHERE routine_name = 'sp1');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`routines` WHERE `routine_name` = 'sp1');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL), new DatabaseScript( "sp2", - $@"SELECT EXISTS(SELECT * FROM information_schema.routines WHERE routine_name = 'sp2');", + $@"SELECT EXISTS(SELECT * FROM `information_schema`.`routines` WHERE `routine_name` = 'sp2');", DatabaseTestType.ObjectExist, DatabaseKind.MySQL) }.ToExpectedObject(); @@ -167,12 +167,14 @@ public async Task MySqlRecordExistScriptTest_Success() var generator = new MySqlTestGenerator(options => { options.AddDatabaseRecordExitsRule( - new List() + new List() { - new DatabaseRule() + new DatabaseRecordExistRule() { TableName = "mytable", - PredicateValue = "name = 'myname'" + ColumnName = "name", + Operator = "=", + Value = "myname" } }); }); @@ -181,7 +183,7 @@ public async Task MySqlRecordExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE name = 'myname');", + $@"SELECT EXISTS(SELECT * FROM `mytable` WHERE `name` = 'myname');", DatabaseTestType.RecordExist, DatabaseKind.MySQL) }.ToExpectedObject(); @@ -189,19 +191,20 @@ public async Task MySqlRecordExistScriptTest_Success() results.ShouldEqual(await generator.Generate()); Assert.Equal(DatabaseKind.MySQL, generator.DatabaseKind); } - + [Fact] public async Task MySqlRecordCountScriptTest_Success() { var generator = new MySqlTestGenerator(options => { options.AddDatabaseRecordsCountRule( - new List() + new List() { - new DatabaseRule() + new DatabaseRecordCountRule() { TableName = "mytable", - PredicateValue = "=100" + Operator = "=", + Count = 100 } }); }); @@ -210,7 +213,7 @@ public async Task MySqlRecordCountScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE (SELECT count(*) FROM mytable)=100);", + $@"SELECT EXISTS (SELECT * FROM `mytable` WHERE (SELECT COUNT(*) AS `count` FROM `mytable`) = 100);", DatabaseTestType.RecordCount, DatabaseKind.MySQL) }.ToExpectedObject(); diff --git a/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs b/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs index 69bdfe7..1653bf7 100644 --- a/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs +++ b/src/QAToolKit.Engine.Database.Test/PostgresqlTestGeneratorTests.cs @@ -21,7 +21,7 @@ public async Task PostgresqlTableExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'mytable');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""tables"" WHERE ""table_name"" = 'mytable');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); @@ -42,7 +42,7 @@ public async Task PostgresqlViewExistScriptTest_Success() { new DatabaseScript( "myview", - $@"SELECT EXISTS (SELECT * FROM information_schema.views WHERE table_name = 'myview');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""views"" WHERE ""table_name"" = 'myview');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); @@ -63,7 +63,7 @@ public async Task PostgresqlStoredProcedureExistScriptTest_Success() { new DatabaseScript( "mystoredprocedure", - $@"SELECT EXISTS (SELECT * FROM information_schema.routines WHERE routine_name = 'mystoredprocedure');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""routines"" WHERE ""routine_name"" = 'mystoredprocedure');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); @@ -84,12 +84,12 @@ public async Task PostgresqlMultipleTableExistScriptTest_Success() { new DatabaseScript( "table1", - $@"SELECT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'table1');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""tables"" WHERE ""table_name"" = 'table1');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL), new DatabaseScript( "table2", - $@"SELECT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'table2');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""tables"" WHERE ""table_name"" = 'table2');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); @@ -110,12 +110,12 @@ public async Task PostgresqlMultipleViewExistScriptTest_Success() { new DatabaseScript( "view1", - $@"SELECT EXISTS (SELECT * FROM information_schema.views WHERE table_name = 'view1');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""views"" WHERE ""table_name"" = 'view1');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL), new DatabaseScript( "view2", - $@"SELECT EXISTS (SELECT * FROM information_schema.views WHERE table_name = 'view2');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""views"" WHERE ""table_name"" = 'view2');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); @@ -136,12 +136,12 @@ public async Task PostgresqlMultipleStoredProcedureExistScriptTest_Success() { new DatabaseScript( "sp1", - $@"SELECT EXISTS (SELECT * FROM information_schema.routines WHERE routine_name = 'sp1');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""routines"" WHERE ""routine_name"" = 'sp1');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL), new DatabaseScript( "sp2", - $@"SELECT EXISTS (SELECT * FROM information_schema.routines WHERE routine_name = 'sp2');", + $@"SELECT EXISTS(SELECT * FROM ""information_schema"".""routines"" WHERE ""routine_name"" = 'sp2');", DatabaseTestType.ObjectExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); @@ -167,12 +167,14 @@ public async Task PostgresqlRecordExistScriptTest_Success() var generator = new PostgresqlTestGenerator(options => { options.AddDatabaseRecordExitsRule( - new List() + new List() { - new DatabaseRule() + new DatabaseRecordExistRule() { TableName = "mytable", - PredicateValue = "name = 'myname'" + ColumnName = "name", + Operator = "=", + Value = "myname" } }); }); @@ -181,7 +183,7 @@ public async Task PostgresqlRecordExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE name = 'myname');", + $@"SELECT EXISTS(SELECT * FROM ""mytable"" WHERE ""name"" = 'myname');", DatabaseTestType.RecordExist, DatabaseKind.PostgreSQL) }.ToExpectedObject(); @@ -196,12 +198,13 @@ public async Task PostgresqlRecordCountScriptTest_Success() var generator = new PostgresqlTestGenerator(options => { options.AddDatabaseRecordsCountRule( - new List() + new List() { - new DatabaseRule() + new DatabaseRecordCountRule() { TableName = "mytable", - PredicateValue = "=100" + Operator = "=", + Count = 100 } }); }); @@ -210,7 +213,7 @@ public async Task PostgresqlRecordCountScriptTest_Success() { new DatabaseScript( "mytable", - $@"SELECT EXISTS (SELECT 1 FROM mytable WHERE (SELECT count(*) FROM mytable)=100);", + $@"SELECT EXISTS (SELECT * FROM ""mytable"" WHERE (SELECT COUNT(*) AS ""count"" FROM ""mytable"") = 100);", DatabaseTestType.RecordCount, DatabaseKind.PostgreSQL) }.ToExpectedObject(); diff --git a/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs b/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs index 4a9f1b9..041dd9f 100644 --- a/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs +++ b/src/QAToolKit.Engine.Database.Test/SqlServerTestGeneratorTests.cs @@ -21,7 +21,7 @@ public async Task SqlServerTableExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"IF EXISTS(SELECT 1 FROM sys.tables WHERE Name = 'mytable') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[tables] WHERE [Name] = 'mytable') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer) }.ToExpectedObject(); @@ -42,7 +42,7 @@ public async Task SqlServerViewExistScriptTest_Success() { new DatabaseScript( "myview", - $@"IF EXISTS(SELECT 1 FROM sys.views WHERE Name = 'myview') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[views] WHERE [Name] = 'myview') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer) }.ToExpectedObject(); @@ -63,7 +63,7 @@ public async Task SqlServerStoredProcedureExistScriptTest_Success() { new DatabaseScript( "mystoredprocedure", - $@"IF EXISTS(SELECT 1 FROM sys.procedures WHERE Name = 'mystoredprocedure') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[procedures] WHERE [Name] = 'mystoredprocedure') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer) }.ToExpectedObject(); @@ -84,12 +84,12 @@ public async Task SqlServerMultipleTableExistScriptTest_Success() { new DatabaseScript( "table1", - $@"IF EXISTS(SELECT 1 FROM sys.tables WHERE Name = 'table1') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[tables] WHERE [Name] = 'table1') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer), new DatabaseScript( "table2", - $@"IF EXISTS(SELECT 1 FROM sys.tables WHERE Name = 'table2') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[tables] WHERE [Name] = 'table2') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer) }.ToExpectedObject(); @@ -110,12 +110,12 @@ public async Task SqlServerMultipleViewExistScriptTest_Success() { new DatabaseScript( "view1", - $@"IF EXISTS(SELECT 1 FROM sys.views WHERE Name = 'view1') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[views] WHERE [Name] = 'view1') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer), new DatabaseScript( "view2", - $@"IF EXISTS(SELECT 1 FROM sys.views WHERE Name = 'view2') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[views] WHERE [Name] = 'view2') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer) }.ToExpectedObject(); @@ -136,12 +136,12 @@ public async Task SqlServerMultipleStoredProcedureExistScriptTest_Success() { new DatabaseScript( "sp1", - $@"IF EXISTS(SELECT 1 FROM sys.procedures WHERE Name = 'sp1') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[procedures] WHERE [Name] = 'sp1') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer), new DatabaseScript( "sp2", - $@"IF EXISTS(SELECT 1 FROM sys.procedures WHERE Name = 'sp2') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [sys].[procedures] WHERE [Name] = 'sp2') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.ObjectExist, DatabaseKind.SQLServer) }.ToExpectedObject(); @@ -168,12 +168,14 @@ public async Task SqlServerRecordExistScriptTest_Success() var generator = new SqlServerTestGenerator(options => { options.AddDatabaseRecordExitsRule( - new List() + new List() { - new DatabaseRule() + new DatabaseRecordExistRule() { TableName = "mytable", - PredicateValue = "name = 'myname'" + ColumnName = "name", + Operator = "=", + Value = "myname" } }); }); @@ -182,7 +184,7 @@ public async Task SqlServerRecordExistScriptTest_Success() { new DatabaseScript( "mytable", - $@"IF EXISTS(SELECT 1 FROM mytable WHERE name = 'myname') BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [mytable] WHERE [name] = 'myname') BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.RecordExist, DatabaseKind.SQLServer) }.ToExpectedObject(); @@ -197,12 +199,13 @@ public async Task SqlServerRecordCountScriptTest_Success() var generator = new SqlServerTestGenerator(options => { options.AddDatabaseRecordsCountRule( - new List() + new List() { - new DatabaseRule() + new DatabaseRecordCountRule() { TableName = "mytable", - PredicateValue = "=100" + Operator = "=", + Count = 100 } }); }); @@ -211,7 +214,7 @@ public async Task SqlServerRecordCountScriptTest_Success() { new DatabaseScript( "mytable", - $@"IF EXISTS(SELECT 1 FROM mytable WHERE (SELECT count(*) FROM mytable)=100) BEGIN Select 1 END ELSE BEGIN Select 0 END", + $@"IF EXISTS (SELECT * FROM [mytable] WHERE (SELECT COUNT(*) AS [count] FROM [mytable]) = 100) BEGIN Select 1 END ELSE BEGIN Select 0 END;", DatabaseTestType.RecordCount, DatabaseKind.SQLServer) }.ToExpectedObject(); diff --git a/src/QAToolKit.Engine.Database/DatabaseTestGeneratorOptions.cs b/src/QAToolKit.Engine.Database/DatabaseTestGeneratorOptions.cs index de9b083..f4cb614 100644 --- a/src/QAToolKit.Engine.Database/DatabaseTestGeneratorOptions.cs +++ b/src/QAToolKit.Engine.Database/DatabaseTestGeneratorOptions.cs @@ -9,8 +9,8 @@ namespace QAToolKit.Engine.Database public class DatabaseTestGeneratorOptions { internal Dictionary DatabaseObjectsExistRules { get; private set; } - internal List DatabaseRecordsCountRules { get; private set; } - internal List DatabaseRecordsExitsRules { get; private set; } + internal List DatabaseRecordsCountRules { get; private set; } + internal List DatabaseRecordsExitsRules { get; private set; } /// /// Add database object exist rules @@ -35,11 +35,11 @@ public DatabaseTestGeneratorOptions AddDatabaseObjectExitsRule(string[] objects, /// /// /// - public DatabaseTestGeneratorOptions AddDatabaseRecordsCountRule(List objects) + public DatabaseTestGeneratorOptions AddDatabaseRecordsCountRule(List objects) { if (DatabaseRecordsCountRules == null) { - DatabaseRecordsCountRules = new List(); + DatabaseRecordsCountRules = new List(); } DatabaseRecordsCountRules.AddRange(objects); @@ -52,11 +52,11 @@ public DatabaseTestGeneratorOptions AddDatabaseRecordsCountRule(List /// /// - public DatabaseTestGeneratorOptions AddDatabaseRecordExitsRule(List objects) + public DatabaseTestGeneratorOptions AddDatabaseRecordExitsRule(List objects) { if (DatabaseRecordsExitsRules == null) { - DatabaseRecordsExitsRules = new List(); + DatabaseRecordsExitsRules = new List(); } DatabaseRecordsExitsRules.AddRange(objects); diff --git a/src/QAToolKit.Engine.Database/Generators/MySqlTestGenerator.cs b/src/QAToolKit.Engine.Database/Generators/MySqlTestGenerator.cs index 4dedea7..0da95ae 100644 --- a/src/QAToolKit.Engine.Database/Generators/MySqlTestGenerator.cs +++ b/src/QAToolKit.Engine.Database/Generators/MySqlTestGenerator.cs @@ -1,5 +1,13 @@ using QAToolKit.Engine.Database.Models; using System; +using SqlKata; +using SqlKata.Compilers; +using SqlKata.Extensions; +using MySql.Data.MySqlClient; +using System.Text.RegularExpressions; +using System.Data; +using System.Data.SqlClient; +using System.Linq; namespace QAToolKit.Engine.Database.Generators { @@ -8,13 +16,17 @@ namespace QAToolKit.Engine.Database.Generators /// public class MySqlTestGenerator : RelationalDatabaseTestGenerator { + private readonly MySqlCompiler mySqlCompiler; + /// /// Create new instance of MySQL script generator /// /// public MySqlTestGenerator(Action options = null) : base(DatabaseKind.MySQL, options) - { } + { + mySqlCompiler = new MySqlCompiler(); + } /// /// Get MySQl script for table exists abstract method @@ -23,7 +35,10 @@ public MySqlTestGenerator(Action options = null) : /// protected override string GetTableExistScript(string table) { - return $@"SELECT EXISTS(SELECT * FROM information_schema.tables WHERE table_name = '{table}');"; + var query = new Query("information_schema.tables").Select("*").Where("table_name", table); + var result = mySqlCompiler.Compile(query); + + return $@"SELECT EXISTS({result});"; } /// @@ -33,7 +48,10 @@ protected override string GetTableExistScript(string table) /// protected override string GetViewExistScript(string view) { - return $@"SELECT EXISTS(SELECT * FROM information_schema.views WHERE table_name = '{view}');"; + var query = new Query("information_schema.views").Select("*").Where("table_name", view); + var result = mySqlCompiler.Compile(query); + + return $@"SELECT EXISTS({result});"; } /// @@ -43,7 +61,10 @@ protected override string GetViewExistScript(string view) /// protected override string GetStoredProcedureExistScript(string storedProcedure) { - return $@"SELECT EXISTS(SELECT * FROM information_schema.routines WHERE routine_name = '{storedProcedure}');"; + var query = new Query("information_schema.routines").Select("*").Where("routine_name", storedProcedure); + var result = mySqlCompiler.Compile(query); + + return $@"SELECT EXISTS({result});"; } /// @@ -51,9 +72,15 @@ protected override string GetStoredProcedureExistScript(string storedProcedure) /// /// /// - protected override string GetRecordExistScript(DatabaseRule recordExist) + protected override string GetRecordExistScript(DatabaseRecordExistRule recordExist) { - return $@"SELECT EXISTS (SELECT 1 FROM {recordExist.TableName} WHERE {recordExist.PredicateValue});"; + var query = new Query(recordExist.TableName) + .Select("*") + .Where(recordExist.ColumnName, recordExist.Operator, recordExist.Value); + + var result = mySqlCompiler.Compile(query); + + return $@"SELECT EXISTS({result});"; } /// @@ -61,9 +88,15 @@ protected override string GetRecordExistScript(DatabaseRule recordExist) /// /// /// - protected override string GetRecordCountScript(DatabaseRule recordCount) + protected override string GetRecordCountScript(DatabaseRecordCountRule recordCount) { - return $@"SELECT EXISTS (SELECT 1 FROM {recordCount.TableName} WHERE (SELECT count(*) FROM {recordCount.TableName}){recordCount.PredicateValue});"; + var countQuery = new Query(recordCount.TableName).AsCount(); + + var query = new Query(recordCount.TableName).Select("*").WhereRaw($"({mySqlCompiler.Compile(countQuery)}) {recordCount.Operator} {recordCount.Count}"); + + var result = mySqlCompiler.Compile(query); + + return $"SELECT EXISTS ({result});"; } } } diff --git a/src/QAToolKit.Engine.Database/Generators/PostgresqlTestGenerator.cs b/src/QAToolKit.Engine.Database/Generators/PostgresqlTestGenerator.cs index 9ce0e85..956cf2a 100644 --- a/src/QAToolKit.Engine.Database/Generators/PostgresqlTestGenerator.cs +++ b/src/QAToolKit.Engine.Database/Generators/PostgresqlTestGenerator.cs @@ -1,4 +1,6 @@ using QAToolKit.Engine.Database.Models; +using SqlKata; +using SqlKata.Compilers; using System; namespace QAToolKit.Engine.Database.Generators @@ -8,13 +10,17 @@ namespace QAToolKit.Engine.Database.Generators /// public class PostgresqlTestGenerator : RelationalDatabaseTestGenerator { + private readonly PostgresCompiler postgresCompiler; + /// /// Create new instance of PostgreSQL script generator /// /// public PostgresqlTestGenerator(Action options = null) : base(DatabaseKind.PostgreSQL, options) - { } + { + postgresCompiler = new PostgresCompiler(); + } /// /// Get PostgreSQL script for table exists abstract method @@ -23,7 +29,9 @@ public PostgresqlTestGenerator(Action options = nu /// protected override string GetTableExistScript(string table) { - return $@"SELECT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = '{table}');"; + var query = new Query("information_schema.tables").Select("*").Where("table_name", table); + var result = postgresCompiler.Compile(query); + return $"SELECT EXISTS({result});"; } /// @@ -33,7 +41,9 @@ protected override string GetTableExistScript(string table) /// protected override string GetViewExistScript(string view) { - return $@"SELECT EXISTS (SELECT * FROM information_schema.views WHERE table_name = '{view}');"; + var query = new Query("information_schema.views").Select("*").Where("table_name", view); + var result = postgresCompiler.Compile(query); + return $"SELECT EXISTS({result});"; } /// @@ -43,7 +53,9 @@ protected override string GetViewExistScript(string view) /// protected override string GetStoredProcedureExistScript(string storedProcedure) { - return $@"SELECT EXISTS (SELECT * FROM information_schema.routines WHERE routine_name = '{storedProcedure}');"; + var query = new Query("information_schema.routines").Select("*").Where("routine_name", storedProcedure); + var result = postgresCompiler.Compile(query); + return $"SELECT EXISTS({result});"; } /// @@ -51,9 +63,15 @@ protected override string GetStoredProcedureExistScript(string storedProcedure) /// /// /// - protected override string GetRecordExistScript(DatabaseRule recordExist) + protected override string GetRecordExistScript(DatabaseRecordExistRule recordExist) { - return $@"SELECT EXISTS (SELECT 1 FROM {recordExist.TableName} WHERE {recordExist.PredicateValue});"; + var query = new Query(recordExist.TableName) + .Select("*") + .Where(recordExist.ColumnName, recordExist.Operator, recordExist.Value); + + var result = postgresCompiler.Compile(query); + + return $"SELECT EXISTS({result});"; } /// @@ -61,9 +79,15 @@ protected override string GetRecordExistScript(DatabaseRule recordExist) /// /// /// - protected override string GetRecordCountScript(DatabaseRule recordCount) + protected override string GetRecordCountScript(DatabaseRecordCountRule recordCount) { - return $@"SELECT EXISTS (SELECT 1 FROM {recordCount.TableName} WHERE (SELECT count(*) FROM {recordCount.TableName}){recordCount.PredicateValue});"; + var countQuery = new Query(recordCount.TableName).AsCount(); + + var query = new Query(recordCount.TableName).Select("*").WhereRaw($"({postgresCompiler.Compile(countQuery)}) {recordCount.Operator} {recordCount.Count}"); + + var result = postgresCompiler.Compile(query); + + return $"SELECT EXISTS ({result});"; } } } diff --git a/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs b/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs index 1f46d2a..8ac85a8 100644 --- a/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs +++ b/src/QAToolKit.Engine.Database/Generators/RelationalDatabaseTestGenerator.cs @@ -212,13 +212,13 @@ private IEnumerable GetStoredProcedureExistScripts() /// /// /// - protected abstract string GetRecordExistScript(DatabaseRule recordExist); + protected abstract string GetRecordExistScript(DatabaseRecordExistRule recordExist); /// /// Get script to count the records in a table /// /// /// - protected abstract string GetRecordCountScript(DatabaseRule recordCount); + protected abstract string GetRecordCountScript(DatabaseRecordCountRule recordCount); } } diff --git a/src/QAToolKit.Engine.Database/Generators/SqlServerTestGenerator.cs b/src/QAToolKit.Engine.Database/Generators/SqlServerTestGenerator.cs index 3bb1281..d0dba67 100644 --- a/src/QAToolKit.Engine.Database/Generators/SqlServerTestGenerator.cs +++ b/src/QAToolKit.Engine.Database/Generators/SqlServerTestGenerator.cs @@ -1,4 +1,6 @@ using QAToolKit.Engine.Database.Models; +using SqlKata; +using SqlKata.Compilers; using System; namespace QAToolKit.Engine.Database.Generators @@ -8,13 +10,17 @@ namespace QAToolKit.Engine.Database.Generators /// public class SqlServerTestGenerator : RelationalDatabaseTestGenerator { + private readonly SqlServerCompiler sqlServerCompiler; + /// /// Create new instance of SqlServer script generator /// /// public SqlServerTestGenerator(Action options = null) : base(DatabaseKind.SQLServer, options) - { } + { + sqlServerCompiler = new SqlServerCompiler(); + } /// /// Get SQL server script for table exists abstract method @@ -23,7 +29,9 @@ public SqlServerTestGenerator(Action options = nul /// protected override string GetTableExistScript(string table) { - return $@"IF EXISTS(SELECT 1 FROM sys.tables WHERE Name = '{table}') BEGIN Select 1 END ELSE BEGIN Select 0 END"; + var query = new Query("sys.tables").Select("*").Where("Name", table); + var result = sqlServerCompiler.Compile(query); + return $"IF EXISTS ({result}) BEGIN Select 1 END ELSE BEGIN Select 0 END;"; } /// @@ -33,7 +41,9 @@ protected override string GetTableExistScript(string table) /// protected override string GetViewExistScript(string view) { - return $@"IF EXISTS(SELECT 1 FROM sys.views WHERE Name = '{view}') BEGIN Select 1 END ELSE BEGIN Select 0 END"; + var query = new Query("sys.views").Select("*").Where("Name", view); + var result = sqlServerCompiler.Compile(query); + return $"IF EXISTS ({result}) BEGIN Select 1 END ELSE BEGIN Select 0 END;"; } /// @@ -43,7 +53,9 @@ protected override string GetViewExistScript(string view) /// protected override string GetStoredProcedureExistScript(string storedProcedure) { - return $@"IF EXISTS(SELECT 1 FROM sys.procedures WHERE Name = '{storedProcedure}') BEGIN Select 1 END ELSE BEGIN Select 0 END"; + var query = new Query("sys.procedures").Select("*").Where("Name", storedProcedure); + var result = sqlServerCompiler.Compile(query); + return $"IF EXISTS ({result}) BEGIN Select 1 END ELSE BEGIN Select 0 END;"; } /// @@ -51,9 +63,17 @@ protected override string GetStoredProcedureExistScript(string storedProcedure) /// /// /// - protected override string GetRecordExistScript(DatabaseRule recordExist) + protected override string GetRecordExistScript(DatabaseRecordExistRule recordExist) { - return $@"IF EXISTS(SELECT 1 FROM {recordExist.TableName} WHERE {recordExist.PredicateValue}) BEGIN Select 1 END ELSE BEGIN Select 0 END"; + //return $@"IF EXISTS(SELECT 1 FROM {recordExist.TableName} WHERE {recordExist.PredicateValue}) BEGIN Select 1 END ELSE BEGIN Select 0 END"; + + var query = new Query(recordExist.TableName) + .Select("*") + .Where(recordExist.ColumnName, recordExist.Operator, recordExist.Value); + + var result = sqlServerCompiler.Compile(query); + + return $"IF EXISTS ({result}) BEGIN Select 1 END ELSE BEGIN Select 0 END;"; } /// @@ -61,9 +81,15 @@ protected override string GetRecordExistScript(DatabaseRule recordExist) /// /// /// - protected override string GetRecordCountScript(DatabaseRule recordCount) + protected override string GetRecordCountScript(DatabaseRecordCountRule recordCount) { - return $@"IF EXISTS(SELECT 1 FROM {recordCount.TableName} WHERE (SELECT count(*) FROM {recordCount.TableName}){recordCount.PredicateValue}) BEGIN Select 1 END ELSE BEGIN Select 0 END"; + var countQuery = new Query(recordCount.TableName).AsCount(); + + var query = new Query(recordCount.TableName).Select("*").WhereRaw($"({sqlServerCompiler.Compile(countQuery)}) {recordCount.Operator} {recordCount.Count}"); + + var result = sqlServerCompiler.Compile(query); + + return $"IF EXISTS ({result}) BEGIN Select 1 END ELSE BEGIN Select 0 END;"; } } } diff --git a/src/QAToolKit.Engine.Database/Models/DatabaseRule.cs b/src/QAToolKit.Engine.Database/Models/DatabaseRecordCountRule.cs similarity index 57% rename from src/QAToolKit.Engine.Database/Models/DatabaseRule.cs rename to src/QAToolKit.Engine.Database/Models/DatabaseRecordCountRule.cs index 3af52fb..9d7bed5 100644 --- a/src/QAToolKit.Engine.Database/Models/DatabaseRule.cs +++ b/src/QAToolKit.Engine.Database/Models/DatabaseRecordCountRule.cs @@ -3,15 +3,19 @@ /// /// Database rule /// - public class DatabaseRule + public class DatabaseRecordCountRule { /// /// Database table name /// public string TableName { get; set; } /// - /// Predicate value + /// Operator /// - public string PredicateValue { get; set; } + public string Operator { get; set; } + /// + /// Value + /// + public long Count { get; set; } } } diff --git a/src/QAToolKit.Engine.Database/Models/DatabaseRecordExistRule.cs b/src/QAToolKit.Engine.Database/Models/DatabaseRecordExistRule.cs new file mode 100644 index 0000000..eb7e68e --- /dev/null +++ b/src/QAToolKit.Engine.Database/Models/DatabaseRecordExistRule.cs @@ -0,0 +1,25 @@ +namespace QAToolKit.Engine.Database.Models +{ + /// + /// Database rule + /// + public class DatabaseRecordExistRule + { + /// + /// Database table name + /// + public string TableName { get; set; } + /// + /// Column name + /// + public string ColumnName { get; set; } + /// + /// Operator + /// + public string Operator { get; set; } + /// + /// Value + /// + public object Value { get; set; } + } +} diff --git a/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj b/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj index 7629a46..92f6b8f 100644 --- a/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj +++ b/src/QAToolKit.Engine.Database/QAToolKit.Engine.Database.csproj @@ -39,6 +39,7 @@ +