├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── SharpData.Sample.Core ├── Example.cs ├── Program.cs ├── SharpData.Sample.Core.csproj └── User.cs ├── SharpData.Sample.NetFull ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── Sample.cs ├── SharpData.Sample.NetFull.csproj └── User.cs ├── SharpData.Tests.Integration ├── App.config ├── AssertSql.cs ├── CollectionAssert.cs ├── ConnectionStrings.cs ├── DBBuilder.cs ├── Data │ ├── DataClientDataTests.cs │ ├── DataClientFactoryTests.cs │ ├── DataClientSchemaTests.cs │ ├── DataClientTests.cs │ ├── DatabaseTests.cs │ └── SpecificExceptionsTests.cs ├── Mysql │ ├── MySqlDataClientFactoryTests.cs │ ├── MySqlDataTests.cs │ └── MySqlSchemaTests.cs ├── Oracle │ ├── OracleManagedDataTests.cs │ ├── OracleManagedDatabaseTests.cs │ ├── OracleOdpDataClientFactoryTests.cs │ ├── OracleOdpDataTests.cs │ ├── OracleOdpDatabaseTests.cs │ ├── OracleOdpSchemaTests.cs │ └── OracleSpecificExceptionsTests.cs ├── PostgreSql │ ├── PostgreSqlDataClientFactoryTests.cs │ ├── PostgreSqlDataTests.cs │ ├── PostgreSqlSchemaTests.cs │ └── PostgreSqlSpecificExceptionsTests.cs ├── Properties │ └── AssemblyInfo.cs ├── SQLite │ ├── SqLiteDataClientFactoryTests.cs │ ├── SqLiteDataTests.cs │ └── SqLiteSchemaTests.cs ├── SharpData.Tests.Integration.csproj ├── SqlServer │ ├── SqlServerDataClientFactoryTests.cs │ ├── SqlServerDataTests.cs │ ├── SqlServerSchemaTests.cs │ └── SqlServerSpecifcExceptionsTests.cs └── packages.config ├── SharpData.Tests ├── AssertSql.cs ├── CollectionAssert.cs ├── DataParameterCollectionFake.cs ├── DataReaderToResultSetMapperTests.cs ├── DatabaseTests.cs ├── Dialects │ ├── Data │ │ ├── DialectDataTests.cs │ │ ├── MySqlDialectTests.cs │ │ ├── OracleDialectTests.cs │ │ ├── PostgreSqlDialectTests.cs │ │ ├── SqLiteDialectTests.cs │ │ └── SqlServerDialectTests.cs │ ├── DialectTests.cs │ └── Schema │ │ ├── DialectSchemaTests.cs │ │ ├── MySqlDialectSchemaTests.cs │ │ ├── OracleDialectSchemaTests.cs │ │ ├── PostgreSqlDialectSchemaTests.cs │ │ ├── SqLiteDialectSchemaTests.cs │ │ └── SqlServerDialectSchemaTests.cs ├── FilterTests.cs ├── Filters │ ├── CompareOperatorToSymbolTests.cs │ └── FilterTests.cs ├── MultipleTableTests.cs ├── ResultSetExtensionsTests.cs ├── Schema │ ├── ColumnTests.cs │ ├── FluentColumnTest.cs │ └── TableTests.cs ├── SharpData.Tests.csproj ├── Util │ └── IntExtensionsTests.cs └── WhereBuilderTests.cs ├── SharpData.sln └── SharpData ├── DataClient.cs ├── DataReaderToResultSetMapper.cs ├── Database.cs ├── Databases ├── DataProvider.cs ├── DatabaseKind.cs ├── DbProviderType.cs ├── Dialect.cs ├── IDbTypeMap.cs ├── MySql │ ├── MySqlDataClient.cs │ ├── MySqlDbFactory.cs │ ├── MySqlDialect.cs │ └── MySqlProvider.cs ├── Oracle │ ├── OracleDataClient.cs │ ├── OracleDialect.cs │ ├── OracleManagedDbFactory.cs │ ├── OracleManagedProvider.cs │ ├── OracleOdpDbFactory.cs │ ├── OracleOdpProvider.cs │ └── OracleReflectionCache.cs ├── PostgreSql │ ├── PostgreDbFactory.cs │ ├── PostgreSqlColumnDialect.cs │ ├── PostgreSqlConstraintsDialect.cs │ ├── PostgreSqlDataClient.cs │ ├── PostgreSqlDbTypesDialect.cs │ ├── PostgreSqlDialect.cs │ ├── PostgreSqlProvider.cs │ ├── PostgreSqlTableDialect.cs │ └── SqlColumnStructure.cs ├── SelectBuilder.cs ├── SqLite │ ├── SQLiteDialect.cs │ ├── SQLiteProvider.cs │ ├── SqLiteDataClient.cs │ └── SqLiteDbFactory.cs ├── SqlServer │ ├── OleDbDbFactory.cs │ ├── SqlDialect.cs │ ├── SqlProvider.cs │ ├── SqlServerDataClient.cs │ └── SqlServerDbFactory.cs └── WhereBuilder.cs ├── DbFactory.cs ├── DefaultDatabase.cs ├── ExceptionHelper.cs ├── Exceptions ├── DataTypeNotAvailableException.cs ├── DatabaseException.cs ├── NotSupportedByDatabaseException.cs ├── NotSupportedByDialect.cs ├── ProviderNotFoundException.cs ├── TableNotFoundException.cs └── UniqueConstraintException.cs ├── FakeDataClient.cs ├── Filters ├── CompareOperator.cs ├── CompareOperatorToSymbol.cs ├── Filter.cs ├── FilterCondition.cs ├── FilterLogic.cs ├── FilterParameter.cs ├── FilterParameterType.cs ├── LogicOperator.cs └── LogicOperatorToSymbol.cs ├── Fluent ├── AddColumn.cs ├── AddComment.cs ├── AddForeignKey.cs ├── AddIndexKey.cs ├── AddPrimaryKey.cs ├── AddTable.cs ├── AddUniqueKey.cs ├── Count.cs ├── DataClientAction.cs ├── DataClientAddIndexKey.cs ├── Delete.cs ├── FluentAdd.cs ├── FluentCount.cs ├── FluentDelete.cs ├── FluentInsert.cs ├── FluentRemove.cs ├── FluentRename.cs ├── FluentScalar.cs ├── FluentSelect.cs ├── FluentUpdate.cs ├── IFluentAdd.cs ├── IFluentModify.cs ├── IFluentRename.cs ├── IRemoveFromTable.cs ├── Insert.cs ├── ModifyColumn.cs ├── RemoveColumn.cs ├── RemoveComment.cs ├── RemoveForeignKey.cs ├── RemoveIndexKey.cs ├── RemoveItem.cs ├── RemovePrimaryKey.cs ├── RemoveTable.cs ├── RemoveUniqueKey.cs ├── RenameColumn.cs ├── RenameTable.cs ├── ReversableFluentActions.cs ├── Select.cs └── Update.cs ├── GenericDbTypeMap.cs ├── IDataClient.cs ├── IDataClientEx.cs ├── IDataClientObjectEx.cs ├── IDataProvider.cs ├── IDatabase.cs ├── ISharpFactory.cs ├── In.cs ├── InOut.cs ├── Log └── SharpDataLogging.cs ├── Out.cs ├── ResultSet.cs ├── ResultSetExtensions.cs ├── Schema ├── Column.cs ├── FluentColumn.cs ├── OnDelete.cs ├── OrderBy.cs ├── OrderByDirection.cs └── Table.cs ├── SharpData.csproj ├── SharpDbConfig.cs ├── SharpFactory.cs ├── TableRow.cs └── Util ├── IntExtensions.cs ├── ReflectionHelper.cs └── StringHelper.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 SharpTools 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SharpData 2 | An awesome ORM for querying and modifying databases 3 | 4 | Nuget package: **install-package sharpdata** 5 | 6 | Supports: 7 | - SqlServer 8 | - Oracle 9 | - Postgre 10 | - Mysql 11 | - SqLite. 12 | 13 | # Usage 14 | 15 | ```cs 16 | using (var client = SharpFactory.Default.CreateDataClient(SqlClientFactory.Instance, "Data Source=(localdb)\\MSSQLLocalDB; Integrated Security=True;")) { 17 | if (client.TableExists("users")) { 18 | client.RemoveTable("users"); 19 | } 20 | 21 | client.AddTable("users", 22 | AutoIncrement("id").AsPrimaryKey(), 23 | String("username", 50).NotNull(), 24 | String("password", 50).NotNull() 25 | ); 26 | client.AddUniqueKey("un_users", "users", "username"); 27 | 28 | client.Insert 29 | .Into("users") 30 | .Columns("username", "password") 31 | .Values("foo1", "bar") 32 | .Values("foo2", "bar") 33 | .Values("foo3", "bar"); 34 | 35 | var users = client.Select 36 | .AllColumns() 37 | .From("users") 38 | .Where(Filter.Eq("username", "foo")) 39 | .OrderBy(OrderBy.Ascending("username")) 40 | .SkipTake(0, 2) 41 | .Map(); 42 | 43 | foreach (var user in users) { 44 | Console.WriteLine("User: " + user.Username); 45 | } 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /SharpData.Sample.Core/Example.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | using SharpData.Filters; 3 | using SharpData.Schema; 4 | using System; 5 | using static SharpData.Schema.Column; 6 | 7 | namespace SharpData.Sample { 8 | public class Example { 9 | 10 | public void Start(IDataClient client) { 11 | if (client.TableExists("users")) { 12 | client.RemoveTable("users"); 13 | } 14 | 15 | client.AddTable("users", 16 | AutoIncrement("id").AsPrimaryKey(), 17 | String("username", 50).NotNull(), 18 | String("password", 50).NotNull() 19 | ); 20 | client.AddUniqueKey("un_users", "users", "username"); 21 | 22 | client.Insert 23 | .Into("users") 24 | .Columns("username", "password") 25 | .Values("foo", "bar") 26 | .Values("foo2", "bar") 27 | .Values("foo3", "bar"); 28 | 29 | var userInsert = new UserInsert { 30 | Username = "ironman", 31 | Password = "superpass" 32 | }; 33 | 34 | client.Insert 35 | .Into("users") 36 | .Object(userInsert); 37 | 38 | userInsert.Username = "hulk"; 39 | 40 | var id = client.Insert 41 | .Into("users") 42 | .ObjectAnd(userInsert) 43 | .Return("Id"); 44 | 45 | var loadedUser = client.LoadById("users", id, u => u.Id); 46 | Console.WriteLine("LoadById User: " + loadedUser.Username); 47 | 48 | 49 | var username = "foo4"; 50 | var password = "bar4"; 51 | client.ExecSqlFormattable($"insert into users (username, password) values ({username}, {password})"); 52 | 53 | var users = client.Select 54 | .AllColumns() 55 | .From("users") 56 | .Where(Filter.Eq("username", "foo")) 57 | .OrderBy(OrderBy.Ascending("username")) 58 | .SkipTake(0, 2) 59 | .Map(); 60 | 61 | Console.WriteLine("Count: " + users.Count); 62 | foreach (var user in users) { 63 | Console.WriteLine("User: " + user.Username); 64 | } 65 | 66 | var filter = "foo%"; 67 | var foos = client.QueryFormattable($"select username, password from users where username like {filter}").Map(); 68 | Console.WriteLine("Count: " + foos.Count); 69 | foreach (var foo in foos) { 70 | Console.WriteLine("Foo: " + foo.Username); 71 | } 72 | Console.WriteLine("End----"); 73 | } 74 | private class Foo { public string Username { get; set; } } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /SharpData.Sample.Core/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.SqlClient; 3 | using Microsoft.Extensions.Logging; 4 | using SharpData.Log; 5 | 6 | namespace SharpData.Sample.Core { 7 | class Program { 8 | static void Main(string[] args) { 9 | SharpDataLogging.LoggerFactory = new LoggerFactory().AddConsole(LogLevel.Debug); 10 | 11 | var factory = new SharpFactory(SqlClientFactory.Instance, "Data Source=(localdb)\\MSSQLLocalDB; Initial Catalog=sharp; Integrated Security=True; Encrypt=False; TrustServerCertificate=True; ApplicationIntent=ReadWrite;"); 12 | using (var client = factory.CreateDataClient()) { 13 | new Example().Start(client); 14 | } 15 | Console.WriteLine("Done"); 16 | Console.ReadLine(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /SharpData.Sample.Core/SharpData.Sample.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /SharpData.Sample.Core/User.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Sample { 2 | public class User { 3 | public int Id { get; set; } 4 | public string Username { get; set; } 5 | public string Password { get; set; } 6 | } 7 | 8 | public class UserInsert { 9 | public string Username { get; set; } 10 | public string Password { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SharpData.Sample.NetFull/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SharpData.Sample.NetFull/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Oracle.ManagedDataAccess.Client; 3 | using SharpData; 4 | 5 | namespace SharpData.Sample.NetFull { 6 | class Program { 7 | static void Main(string[] args) { 8 | SharpFactory.Default = new SharpFactory(new OracleClientFactory(), "Data Source=//localhost/XE;User Id=sharp;Password=sharp;"); 9 | 10 | using (var client = 11 | SharpFactory.Default.CreateDataClient()) { 12 | new Sample().Start(client); 13 | } 14 | Console.WriteLine("Done"); 15 | Console.ReadLine(); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /SharpData.Sample.NetFull/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SharpData.Sample.Net452")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SharpData.Sample.Net452")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0802e465-ba2f-4f06-88df-b8a833752ef8")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SharpData.Sample.NetFull/Sample.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | using SharpData.Filters; 3 | using System; 4 | using System.Linq; 5 | using static SharpData.Schema.Column; 6 | 7 | namespace SharpData.Sample { 8 | public class Sample { 9 | 10 | public void Start(IDataClient client) { 11 | if (client.TableExists("users")) { 12 | client.RemoveTable("users"); 13 | } 14 | 15 | client.AddTable("users", 16 | AutoIncrement("id").AsPrimaryKey(), 17 | String("username", 50).NotNull(), 18 | String("password", 50).NotNull() 19 | ); 20 | client.AddUniqueKey("un_users", "users", "username"); 21 | 22 | client.Insert 23 | .Into("users") 24 | .Columns("username", "password") 25 | .Values("foo", "bar"); 26 | 27 | var users = client.Select 28 | .AllColumns() 29 | .From("users") 30 | .Where(Filter.Eq("username", "foo")) 31 | .SkipTake(0, 1) 32 | .Map(); 33 | 34 | foreach (var user in users) { 35 | Console.WriteLine("User: " + user.Username); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SharpData.Sample.NetFull/SharpData.Sample.NetFull.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0802E465-BA2F-4F06-88DF-B8A833752EF8} 8 | Exe 9 | SharpData.Sample.NetFull 10 | SharpData.Sample.NetFull 11 | v4.6 12 | 512 13 | true 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {114dcb49-5b78-4d87-a02d-918561d7799c} 56 | SharpData 57 | 58 | 59 | 60 | 61 | 12.2.1100 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /SharpData.Sample.NetFull/User.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Sample { 2 | public class User { 3 | public int Id { get; set; } 4 | public string Username { get; set; } 5 | public string Password { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SharpData.Tests.Integration/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /SharpData.Tests.Integration/AssertSql.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace SharpData.Tests.Databases { 4 | public static class AssertSql { 5 | 6 | public static void AreEqual(string sql1, string sql2) { 7 | sql1 = sql1.Trim().Replace("\r\n", "").Replace(", ",",").ToUpper(); 8 | sql2 = sql2.Trim().Replace("\r\n", "").Replace(", ", ",").ToUpper(); 9 | Assert.Equal(sql1,sql2); 10 | } 11 | 12 | public static void AreEqual(string[] sqls1, string[] sqls2) { 13 | Assert.True(sqls1.Length == sqls2.Length, $"Sizes doesn't match: {sqls1.Length} != {sqls2.Length}"); 14 | for (var i = 0; i < sqls1.Length; i++) { 15 | AreEqual(sqls1[i],sqls2[2]); 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/CollectionAssert.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using Xunit; 3 | 4 | namespace SharpData.Tests.Integration { 5 | public static class CollectionAssert { 6 | public static void AreEqual(ICollection expected, ICollection actual) { 7 | Assert.True(expected.Count == actual.Count, "Collections are not the same size"); 8 | var actualEnumerator = actual.GetEnumerator(); 9 | 10 | foreach (var item in expected) { 11 | actualEnumerator.MoveNext(); 12 | var other = actualEnumerator.Current; 13 | Assert.True(item.Equals(other)); 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/ConnectionStrings.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Tests.Integration { 2 | public static class ConnectionStrings { 3 | public static string Oracle = "Data Source=//localhost:1521/XE; User Id=sharp; Password=sharp;"; 4 | public static string Mysql = "Server=localhost;Port=3306;Database=sharp;Uid=sharp;Pwd=sharp;"; 5 | public static string Sqlite = "Data Source=sharp.db3;"; 6 | public static string SqlServer = "Server=(localdb)\\mssqllocaldb;Database=sharp;Trusted_Connection=True;MultipleActiveResultSets=true"; 7 | public static string Postgre = "User ID=sharp;Password=sharp;Host=localhost;Port=5432;Database=sharp;"; 8 | } 9 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/DBBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Common; 4 | using System.Data.SqlClient; 5 | using System.Data.SQLite; 6 | using MySql.Data.MySqlClient; 7 | using Npgsql; 8 | using SharpData.Databases; 9 | using OracleClientFactory = Oracle.ManagedDataAccess.Client.OracleClientFactory; 10 | using OracleDataAccess = Oracle.DataAccess.Client; 11 | 12 | namespace SharpData.Tests.Integration { 13 | public static class DBBuilder { 14 | private static Dictionary _factories = new Dictionary(); 15 | 16 | static DBBuilder() { 17 | AddFactoryOrNull(DbProviderType.SqlServer, ConnectionStrings.SqlServer, () => SqlClientFactory.Instance); 18 | AddFactoryOrNull(DbProviderType.MySql, ConnectionStrings.Mysql, () => new MySqlClientFactory()); 19 | AddFactoryOrNull(DbProviderType.OracleManaged, ConnectionStrings.Oracle, () => new OracleClientFactory()); 20 | AddFactoryOrNull(DbProviderType.OracleOdp, ConnectionStrings.Oracle, () => new OracleDataAccess.OracleClientFactory()); 21 | AddFactoryOrNull(DbProviderType.PostgreSql, ConnectionStrings.Postgre, () => NpgsqlFactory.Instance); 22 | AddFactoryOrNull(DbProviderType.SqLite, ConnectionStrings.Sqlite, () => SQLiteFactory.Instance); 23 | } 24 | 25 | public static void AddFactoryOrNull(DbProviderType dbProviderType, 26 | string connectionString, 27 | Func createAction) { 28 | DbProviderFactory factory = null; 29 | try { 30 | factory = createAction.Invoke(); 31 | } 32 | catch { 33 | //sorry, continue the other tests 34 | } 35 | _factories.Add(dbProviderType, new SharpFactory(factory, ConnectionStrings.SqlServer)); 36 | } 37 | 38 | public static IDataClient GetDataClient(DbProviderType databaseProvider) { 39 | return _factories[databaseProvider].CreateDataClient(); 40 | } 41 | 42 | public static string GetConnectionString(DbProviderType databaseProvider) { 43 | return _factories[databaseProvider].ConnectionString; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Data/DataClientFactoryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using Xunit; 4 | 5 | namespace SharpData.Tests.Integration.Data { 6 | public abstract class DataClientFactoryTests { 7 | public IDataClient CreateDataClient() { 8 | return DBBuilder.GetDataClient(GetDatabaseType()); 9 | } 10 | 11 | [Fact] 12 | public virtual void Can_create_dataclient() { 13 | var client = CreateDataClient(); 14 | 15 | //check connection string 16 | Assert.Equal(DBBuilder.GetConnectionString(GetDatabaseType()), client.Database.ConnectionString); 17 | 18 | //check DataClient type 19 | Assert.True(client.GetType() == GetDataClientType()); 20 | 21 | //check Dialect type 22 | Assert.True(client.Dialect.GetType() == GetDialectType()); 23 | } 24 | 25 | public abstract DbProviderType GetDatabaseType(); 26 | public abstract Type GetDataProviderType(); 27 | public abstract Type GetDataClientType(); 28 | public abstract Type GetDialectType(); 29 | } 30 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Data/DataClientTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Schema; 4 | using Xunit; 5 | 6 | namespace SharpData.Tests.Integration.Data { 7 | 8 | public abstract class DataClientTests : IDisposable { 9 | protected string TableFoo = "foo"; 10 | private IDataClient _dataClient; 11 | 12 | protected IDataClient DataClient => _dataClient ?? (_dataClient = DBBuilder.GetDataClient(GetDataProviderName())); 13 | 14 | protected abstract DbProviderType GetDataProviderName(); 15 | 16 | protected DataClientTests() { 17 | CleanTables(); 18 | } 19 | 20 | [Fact] 21 | public void Should_return_false_if_table_doesnt_exist() { 22 | Assert.False(DataClient.TableExists("foo")); 23 | } 24 | 25 | [Fact] 26 | public void Should_return_true_if_table_exists() { 27 | CreateTableFoo(); 28 | Assert.True(DataClient.TableExists("foo")); 29 | } 30 | 31 | protected void CreateTableFoo() { 32 | DataClient.AddTable(TableFoo, 33 | Column.Int32("id").AsPrimaryKey(), 34 | Column.String("name") 35 | ); 36 | } 37 | 38 | protected void PopulateTableFoo() { 39 | DataClient.Insert.Into(TableFoo) 40 | .Columns("id", "name") 41 | .Values(1, "v1") 42 | .Values(2, "v2") 43 | .Values(3, "v3"); 44 | } 45 | 46 | protected void CreateTableBar() { 47 | DataClient.AddTable("bar", 48 | Column.Int32("id").AsPrimaryKey(), 49 | Column.Int32("id_foo1").NotNull(), 50 | Column.Int32("id_foo2").NotNull(), 51 | Column.String("name") 52 | ); 53 | } 54 | 55 | 56 | protected void DropTable(string tableName) { 57 | try { 58 | DataClient.RemoveTable(tableName); 59 | } 60 | catch {} 61 | } 62 | 63 | public void CleanTables() { 64 | DropTable(TableFoo); 65 | DropTable("bar"); 66 | DropTable("foobar"); 67 | DropTable("footable"); 68 | } 69 | 70 | public void Dispose() { 71 | CleanTables(); 72 | DataClient.RollBack(); 73 | DataClient.Dispose(); 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Mysql/MySqlDataClientFactoryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Databases.MySql; 4 | using SharpData.Tests.Integration.Data; 5 | 6 | namespace SharpData.Tests.Integration.Mysql { 7 | public class MySqlDataClientFactoryTests : DataClientFactoryTests { 8 | public override DbProviderType GetDatabaseType() { 9 | return DbProviderType.MySql; 10 | } 11 | 12 | public override Type GetDataProviderType() { 13 | return typeof(MySqlProvider); 14 | } 15 | 16 | public override Type GetDataClientType() { 17 | return typeof(MySqlDataClient); 18 | } 19 | 20 | public override Type GetDialectType() { 21 | return typeof(MySqlDialect); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Mysql/MySqlDataTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Schema; 3 | using SharpData.Tests.Integration.Data; 4 | using Xunit; 5 | 6 | namespace SharpData.Tests.Integration.Mysql { 7 | public class MySqlDataTests : DataClientDataTests { 8 | protected override DbProviderType GetDataProviderName() { 9 | return DbProviderType.MySql; 10 | } 11 | 12 | [Fact(Skip = "Not implemented yet. Pull requests welcome!")] 13 | public override void Can_insert_returning_id() { 14 | DataClient.AddTable("footable", 15 | Column.AutoIncrement("id"), 16 | Column.String("name") 17 | ); 18 | Assert.Equal(1, DataClient.Insert.Into("footable").Columns("name").ValuesAnd("asdf").Return("id")); 19 | Assert.Equal(2, DataClient.Insert.Into("footable").Columns("name").ValuesAnd("asdf").Return("id")); 20 | Assert.Equal(3, DataClient.Insert.Into("footable").Columns("name").ValuesAnd("asdf").Return("id")); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Mysql/MySqlSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Exceptions; 3 | using SharpData.Schema; 4 | using SharpData.Tests.Integration.Data; 5 | using Xunit; 6 | 7 | namespace SharpData.Tests.Integration.Mysql { 8 | public class MySqlSchemaTests : DataClientSchemaTests { 9 | protected override DbProviderType GetDataProviderName() { 10 | return DbProviderType.MySql; 11 | } 12 | 13 | [Fact] 14 | public override void Can_create_table_with_autoIncrement() { 15 | Assert.Throws(() => { 16 | DataClient.AddTable(TableFoo, 17 | Column.AutoIncrement("id"), 18 | Column.String("name")); 19 | }); 20 | } 21 | 22 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 23 | public override void Can_add_comment_to_column() { 24 | } 25 | 26 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 27 | public override void Can_add_comment_to_table() { 28 | } 29 | 30 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 31 | public override void Can_add_foreign_key_to_table() { 32 | } 33 | 34 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 35 | public override void Can_add_unique_constraint() { 36 | } 37 | 38 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 39 | public override void Can_modify_column() { 40 | } 41 | 42 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 43 | public override void Can_remove_foreign_key_from_table() { 44 | } 45 | 46 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 47 | public override void Can_remove_unique_constraint() { 48 | } 49 | 50 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 51 | public override void Can_rename_table() { 52 | 53 | } 54 | 55 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 56 | public override void Can_rename_column() { 57 | 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Oracle/OracleManagedDataTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Schema; 4 | using SharpData.Tests.Integration.Data; 5 | using Xunit; 6 | 7 | namespace SharpData.Tests.Integration.Oracle { 8 | public class OracleManagedDataTests : DataClientDataTests { 9 | protected override DbProviderType GetDataProviderName() { 10 | return DbProviderType.OracleManaged; 11 | } 12 | 13 | public override void Can_insert_dates_and_booleans() { 14 | DataClient.AddTable("footable", 15 | Column.AutoIncrement("id"), 16 | Column.Date("colDate"), 17 | Column.Boolean("colBool")); 18 | 19 | 20 | var now = DateTime.Now; 21 | DataClient.Insert.Into("footable").Columns("colDate", "colBool").Values(now, true); 22 | var res = DataClient.Select.Columns("colDate", "colBool").From("footable").AllRows(); 23 | Assert.Equal(now.ToString(), res[0][0].ToString()); 24 | Assert.Equal((short)1, res[0][1]); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Oracle/OracleOdpDataClientFactoryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Databases.Oracle; 4 | using SharpData.Tests.Integration.Data; 5 | 6 | namespace SharpData.Tests.Integration.Oracle { 7 | public class OracleOdpDataClientFactoryTests : DataClientFactoryTests { 8 | public override DbProviderType GetDatabaseType() { 9 | return DbProviderType.OracleOdp; 10 | } 11 | 12 | public override Type GetDataProviderType() { 13 | return typeof(OracleOdpProvider); 14 | } 15 | 16 | public override Type GetDataClientType() { 17 | return typeof(OracleDataClient); 18 | } 19 | 20 | public override Type GetDialectType() { 21 | return typeof(OracleDialect); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Oracle/OracleOdpDataTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Schema; 4 | using SharpData.Tests.Integration.Data; 5 | using Xunit; 6 | 7 | namespace SharpData.Tests.Integration.Oracle { 8 | 9 | public class OracleOdpDataTests : DataClientDataTests { 10 | 11 | protected override DbProviderType GetDataProviderName() { 12 | return DbProviderType.OracleOdp; 13 | } 14 | 15 | public override void Can_insert_dates_and_booleans() { 16 | DataClient.AddTable("footable", 17 | Column.AutoIncrement("id"), 18 | Column.Date("colDate"), 19 | Column.Boolean("colBool")); 20 | 21 | 22 | var now = DateTime.Now; 23 | DataClient.Insert.Into("footable").Columns("colDate", "colBool").Values(now, true); 24 | var res = DataClient.Select.Columns("colDate", "colBool").From("footable").AllRows(); 25 | Assert.Equal(now.ToString(), res[0][0].ToString()); 26 | Assert.Equal(1, Convert.ToInt32(res[0][1])); 27 | } 28 | 29 | } 30 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Oracle/OracleOdpDatabaseTests.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using SharpData.Databases; 3 | using SharpData.Databases.Oracle; 4 | using SharpData.Util; 5 | 6 | namespace SharpData.Tests.Integration.Oracle { 7 | 8 | public class OracleOdpDatabaseTests : OracleManagedDatabaseTests { 9 | 10 | public OracleOdpDatabaseTests() { 11 | 12 | } 13 | 14 | protected override DbProviderType GetDataProviderName() { 15 | return DbProviderType.OracleOdp; 16 | } 17 | 18 | public override void Dispose() { 19 | base.Dispose(); 20 | typeof(OracleOdpProvider).GetTypeInfo().GetField("_reflectionCache", ReflectionHelper.NoRestrictions) 21 | .SetValue(null, new OracleReflectionCache()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Oracle/OracleOdpSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.Oracle { 5 | public class OracleOdpSchemaTests : DataClientSchemaTests { 6 | protected override DbProviderType GetDataProviderName() { 7 | return DbProviderType.OracleOdp; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Oracle/OracleSpecificExceptionsTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.Oracle { 5 | public class OracleSpecificExceptionsTests : SpecificExceptionsTests { 6 | public OracleSpecificExceptionsTests() { 7 | _dataClient = DBBuilder.GetDataClient(DbProviderType.OracleOdp); 8 | _database = _dataClient.Database; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/PostgreSql/PostgreSqlDataClientFactoryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Databases.PostgreSql; 4 | using SharpData.Tests.Integration.Data; 5 | 6 | namespace SharpData.Tests.Integration.PostgreSql { 7 | public class PostgreSqlDataClientFactoryTests : DataClientFactoryTests { 8 | 9 | public override DbProviderType GetDatabaseType() { 10 | return DbProviderType.PostgreSql; 11 | } 12 | 13 | public override Type GetDataProviderType() { 14 | return typeof(PostgreSqlProvider); 15 | } 16 | 17 | public override Type GetDataClientType() { 18 | return typeof(PostgreSqlDataClient); 19 | } 20 | 21 | public override Type GetDialectType() { 22 | return typeof(PostgreSqlDialect); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SharpData.Tests.Integration/PostgreSql/PostgreSqlDataTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.PostgreSql { 5 | public class PostgreSqlDataTests : DataClientDataTests { 6 | protected override DbProviderType GetDataProviderName() { 7 | return DbProviderType.PostgreSql; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/PostgreSql/PostgreSqlSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.PostgreSql { 5 | public class PostgreSqlSchemaTests : DataClientSchemaTests { 6 | protected override DbProviderType GetDataProviderName() { 7 | return DbProviderType.PostgreSql; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/PostgreSql/PostgreSqlSpecificExceptionsTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.PostgreSql { 5 | public class PostgreSqlSpecificExceptionsTests : SpecificExceptionsTests { 6 | public PostgreSqlSpecificExceptionsTests() { 7 | _dataClient = DBBuilder.GetDataClient(DbProviderType.PostgreSql); 8 | _database = _dataClient.Database; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SharpData.Tests.Integration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SharpData.Tests.Integration")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SharpData.Tests.Integration")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("91821aff-e056-4556-930f-130b108c6e7c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SharpData.Tests.Integration/SQLite/SqLiteDataClientFactoryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Databases.SqLite; 4 | using SharpData.Tests.Integration.Data; 5 | 6 | namespace SharpData.Tests.Integration.SQLite { 7 | public class SqLiteDataClientFactoryTests : DataClientFactoryTests { 8 | public override DbProviderType GetDatabaseType() { 9 | return DbProviderType.SqLite; 10 | } 11 | 12 | public override Type GetDataProviderType() { 13 | return typeof(SqLiteProvider); 14 | } 15 | 16 | public override Type GetDataClientType() { 17 | return typeof(SqLiteDataClient); 18 | } 19 | 20 | public override Type GetDialectType() { 21 | return typeof(SqLiteDialect); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/SQLite/SqLiteDataTests.cs: -------------------------------------------------------------------------------- 1 | using System.Data.SQLite; 2 | using System.IO; 3 | using SharpData.Databases; 4 | using SharpData.Exceptions; 5 | using SharpData.Tests.Integration.Data; 6 | using Xunit; 7 | 8 | namespace SharpData.Tests.Integration.SQLite { 9 | public class SqLiteDataTests : DataClientDataTests { 10 | public SqLiteDataTests() { 11 | var fileName = "hot.db3"; 12 | if (File.Exists(fileName)) { 13 | File.Delete(fileName); 14 | } 15 | SQLiteConnection.CreateFile(fileName); 16 | } 17 | 18 | protected override DbProviderType GetDataProviderName() { 19 | return DbProviderType.SqLite; 20 | } 21 | 22 | [Fact] 23 | public override void Can_insert_returning_id() { 24 | var ex = Assert.Throws(() => { base.Can_insert_returning_id(); }); 25 | Assert.Equal(ex.DialectName, "SqLiteDialect"); 26 | Assert.Equal(ex.FunctionName, "GetInsertReturningColumnSql"); 27 | } 28 | 29 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 30 | public override void Can_order_by_with_filter_and_pagination() { 31 | } 32 | 33 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 34 | public override void Can_select_with_pagination() { 35 | } 36 | 37 | [Fact(Skip = "Not implemented. Pull requests welcome :)")] 38 | public override void Can_select_with_pagination_and_where_filter() { 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/SQLite/SqLiteSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using System.Data.SQLite; 2 | using System.IO; 3 | using SharpData.Databases; 4 | using SharpData.Exceptions; 5 | using SharpData.Tests.Integration.Data; 6 | using Xunit; 7 | 8 | namespace SharpData.Tests.Integration.SQLite { 9 | public class SqLiteSchemaTests : DataClientSchemaTests { 10 | public SqLiteSchemaTests() { 11 | var fileName = "hot.db3"; 12 | if (File.Exists(fileName)) { 13 | File.Delete(fileName); 14 | } 15 | SQLiteConnection.CreateFile(fileName); 16 | } 17 | 18 | protected override DbProviderType GetDataProviderName() { 19 | return DbProviderType.SqLite; 20 | } 21 | 22 | [Fact] 23 | public override void Can_add_foreign_key_to_table() { 24 | try { 25 | base.Can_add_foreign_key_to_table(); 26 | Assert.True(false); 27 | } 28 | catch (NotSupportedByDialectException ex) { 29 | Assert.Equal(ex.DialectName, "SqLiteDialect"); 30 | Assert.Equal(ex.FunctionName, "GetForeignKeySql"); 31 | } 32 | } 33 | 34 | [Fact] 35 | public override void Can_add_named_primary_key_to_table() { 36 | try { 37 | base.Can_add_named_primary_key_to_table(); 38 | Assert.True(false); 39 | } 40 | catch (NotSupportedByDialectException ex) { 41 | Assert.Equal(ex.DialectName, "SqLiteDialect"); 42 | Assert.Equal(ex.FunctionName, "GetPrimaryKeySql"); 43 | } 44 | } 45 | 46 | [Fact] 47 | public override void Can_add_primary_key_to_table() { 48 | try { 49 | base.Can_add_primary_key_to_table(); 50 | Assert.True(false); 51 | } 52 | catch (NotSupportedByDialectException ex) { 53 | Assert.Equal(ex.DialectName, "SqLiteDialect"); 54 | Assert.Equal(ex.FunctionName, "GetPrimaryKeySql"); 55 | } 56 | } 57 | 58 | [Fact] 59 | public override void Can_remove_column_from_table() { 60 | try { 61 | base.Can_remove_column_from_table(); 62 | Assert.True(false); 63 | } 64 | catch (NotSupportedByDialectException ex) { 65 | Assert.Equal(ex.DialectName, "SqLiteDialect"); 66 | Assert.Equal(ex.FunctionName, "GetDropColumnSql"); 67 | } 68 | } 69 | 70 | 71 | [Fact] 72 | public override void Can_remove_foreign_key_from_table() { 73 | try { 74 | DataClient.RemoveForeignKey("foo", "bar"); 75 | Assert.True(false); 76 | } 77 | catch (NotSupportedByDialectException ex) { 78 | Assert.Equal(ex.DialectName, "SqLiteDialect"); 79 | Assert.Equal(ex.FunctionName, "GetDropForeignKeySql"); 80 | } 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/SqlServer/SqlServerDataClientFactoryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases; 3 | using SharpData.Databases.SqlServer; 4 | using SharpData.Tests.Integration.Data; 5 | 6 | namespace SharpData.Tests.Integration.SqlServer { 7 | public class SqlServerDataClientFactoryTests : DataClientFactoryTests { 8 | public override DbProviderType GetDatabaseType() { 9 | return DbProviderType.SqlServer; 10 | } 11 | 12 | public override Type GetDataProviderType() { 13 | return typeof(SqlProvider); 14 | } 15 | 16 | public override Type GetDataClientType() { 17 | return typeof(SqlServerDataClient); 18 | } 19 | 20 | public override Type GetDialectType() { 21 | return typeof(SqlDialect); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/SqlServer/SqlServerDataTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.SqlServer { 5 | public class SqlServerDataTests : DataClientDataTests { 6 | protected override DbProviderType GetDataProviderName() { 7 | return DbProviderType.SqlServer; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/SqlServer/SqlServerSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.SqlServer { 5 | public class SqlServerSchemaTests : DataClientSchemaTests { 6 | protected override DbProviderType GetDataProviderName() { 7 | return DbProviderType.SqlServer; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /SharpData.Tests.Integration/SqlServer/SqlServerSpecifcExceptionsTests.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Databases; 2 | using SharpData.Tests.Integration.Data; 3 | 4 | namespace SharpData.Tests.Integration.SqlServer { 5 | public class SqlServerSpecifcExceptionsTests : SpecificExceptionsTests { 6 | public SqlServerSpecifcExceptionsTests() { 7 | _dataClient = DBBuilder.GetDataClient(DbProviderType.SqlServer); 8 | _database = _dataClient.Database; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /SharpData.Tests/AssertSql.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | using Xunit; 3 | 4 | namespace Sharp.Tests { 5 | public static class AssertSql { 6 | private static string FormatSqlForTesting(string value) { 7 | value = Regex.Replace(value, @"\s+", " "); 8 | return value.Trim() 9 | .Replace("\n", "") 10 | .Replace("\r", "") 11 | .Replace(", ", ",") 12 | .Replace(" ,", ",") 13 | .Replace("( ", "(") 14 | .Replace(" (", "(") 15 | .Replace(" )", ")") 16 | .Replace(" ", " ") 17 | .ToLower(); 18 | } 19 | 20 | public static void AreEqual(string[] sqls1, string[] sqls2) { 21 | Assert.Equal(sqls1.Length, sqls2.Length); 22 | for (var i = 0; i < sqls1.Length; i++) { 23 | AreEqual(sqls1[i], sqls2[i]); 24 | } 25 | } 26 | public static void AreEqual(string sql1, string sql2) { 27 | Assert.Equal(FormatSqlForTesting(sql1), FormatSqlForTesting(sql2)); 28 | } 29 | 30 | } 31 | } -------------------------------------------------------------------------------- /SharpData.Tests/CollectionAssert.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using Xunit; 3 | 4 | namespace SharpData.Tests { 5 | public static class CollectionAssert { 6 | public static void AreEqual(ICollection expected, ICollection actual) { 7 | Assert.True(expected.Count == actual.Count, "Collections are not the same size"); 8 | var actualEnumerator = actual.GetEnumerator(); 9 | 10 | foreach (var item in expected) { 11 | actualEnumerator.MoveNext(); 12 | var other = actualEnumerator.Current; 13 | Assert.True(item.Equals(other)); 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SharpData.Tests/DataParameterCollectionFake.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | 5 | namespace Sharp.Tests.Data { 6 | public class DataParameterCollectionFake : List, IDataParameterCollection { 7 | 8 | public void RemoveAt(string parameterName) { 9 | 10 | } 11 | 12 | public object this[string parameterName] { 13 | get => this[parameterName]; 14 | set => this[parameterName] = value; 15 | } 16 | 17 | public bool Contains(string parameterName) { 18 | throw new NotImplementedException(); 19 | } 20 | 21 | public int IndexOf(string parameterName) { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /SharpData.Tests/DataReaderToResultSetMapperTests.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | using Moq; 3 | using Xunit; 4 | using SharpData; 5 | using SharpData.Tests; 6 | 7 | namespace Sharp.Tests.Data { 8 | public class DataReaderToResultSetMapperTests { 9 | 10 | [Fact] 11 | public void Can_map_selects_with_columns() { 12 | var reader = new Mock(); 13 | reader.Setup(x => x.GetName(0)).Returns("col1"); 14 | reader.Setup(x => x.GetName(1)).Returns("col2"); 15 | reader.Setup(x => x.FieldCount).Returns(2); 16 | var result = DataReaderToResultSetMapper.Map(reader.Object); 17 | CollectionAssert.AreEqual(new[] { "col1", "col2" }, result.GetColumnNames()); 18 | } 19 | 20 | [Fact] 21 | public void Can_map_selects_with_two_columns_with_the_same_name() { 22 | var reader = new Mock(); 23 | reader.Setup(x => x.GetName(0)).Returns("col"); 24 | reader.Setup(x => x.GetName(1)).Returns("colx"); 25 | reader.Setup(x => x.GetName(2)).Returns("col"); 26 | reader.Setup(x => x.FieldCount).Returns(3); 27 | var result = DataReaderToResultSetMapper.Map(reader.Object); 28 | CollectionAssert.AreEqual(new [] {"col", "colx", "col_2"}, result.GetColumnNames()); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Data/MySqlDialectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using SharpData.Databases.MySql; 4 | 5 | namespace Sharp.Tests.Databases.Mysql { 6 | 7 | public class MySqlDialectDataTests : DialectDataTests { 8 | 9 | public MySqlDialectDataTests() { 10 | _dialect = new MySqlDialect(); 11 | } 12 | 13 | protected override string GetResultFor_Can_create_check_if_table_exists_sql() { 14 | return 15 | "select count(table_name) from information_schema.tables where table_schema = SCHEMA() and table_name = 'mytable'"; 16 | } 17 | 18 | protected override string GetResultFor_Can_generate_count_sql() { 19 | return "SELECT COUNT(*) FROM myTable"; 20 | } 21 | 22 | protected override string GetResultFor_Can_generate_select_sql_with_pagination(int skip, int to) { 23 | return "select * from mytable limit 10,20"; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Data/OracleDialectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using SharpData; 4 | using SharpData.Databases.Oracle; 5 | 6 | namespace Sharp.Tests.Databases.Oracle { 7 | 8 | public class OracleDialectDataTests : DialectDataTests { 9 | 10 | public OracleDialectDataTests() { 11 | _dialect = new OracleDialect(); 12 | } 13 | 14 | protected override string GetResultFor_Can_create_check_if_table_exists_sql() { 15 | return "select count(table_name) from user_tables where upper(table_name) = upper('" + TABLE_NAME + "')"; 16 | } 17 | 18 | protected override string GetResultFor_Can_generate_count_sql() { 19 | return "SELECT COUNT(*) FROM MYTABLE"; 20 | } 21 | 22 | protected override string GetResultFor_Can_generate_select_sql_with_pagination(int skip, int take) { 23 | string sql = GetSelectAllSql(); 24 | string innerSql = String.Format("select /* FIRST_ROWS(n) */ a.*, ROWNUM rnum from ({0}) a where ROWNUM <= {1}", sql, skip + take); 25 | return String.Format("select * from ({0}) where rnum > {1}", innerSql, skip); 26 | } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Data/PostgreSqlDialectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using SharpData.Databases.PostgreSql; 4 | 5 | namespace Sharp.Tests.Databases.PostgreSql { 6 | public class PostgreSqlDialectTests : DialectDataTests { 7 | public PostgreSqlDialectTests() { 8 | _dialect = new PostgreSqlDialect(); 9 | } 10 | 11 | protected override string GetResultFor_Can_create_check_if_table_exists_sql() { 12 | return String.Format("SELECT COUNT(relname) FROM pg_class WHERE relname = '{0}'", TABLE_NAME); 13 | } 14 | 15 | protected override string GetResultFor_Can_generate_count_sql() { 16 | return "SELECT COUNT(*) FROM MYTABLE"; 17 | } 18 | 19 | protected override string GetResultFor_Can_generate_select_sql_with_pagination(int skip, int to) { 20 | var sql = GetSelectAllSql(); 21 | return String.Format("SELECT * FROM ({0}) AS TEMP OFFSET {1} LIMIT {2}", sql, skip, to); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Data/SqLiteDialectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using SharpData.Databases.SqLite; 4 | 5 | namespace Sharp.Tests.Databases.SQLite { 6 | 7 | public class SqLiteDialectDataTests : DialectDataTests { 8 | public SqLiteDialectDataTests() { 9 | _dialect = new SqLiteDialect(); 10 | } 11 | 12 | protected override string GetResultFor_Can_create_check_if_table_exists_sql() { 13 | return "SELECT count(name) FROM sqlite_master WHERE upper(name)=upper('" + TABLE_NAME + "')"; 14 | } 15 | 16 | protected override string GetResultFor_Can_generate_count_sql() { 17 | return "SELECT COUNT(*) FROM myTable"; 18 | } 19 | 20 | protected override string GetResultFor_Can_generate_select_sql_with_pagination(int skip, int to) { 21 | throw new NotImplementedException(); 22 | } 23 | 24 | [Fact(Skip = "Not supported by SqLite")] 25 | public override void Can_generate_select_sql_with_pagination() { 26 | 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Data/SqlServerDialectTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Xunit; 6 | using SharpData.Databases.SqlServer; 7 | 8 | namespace Sharp.Tests.Databases.SqlServer { 9 | public class SqlServerDialectDataTests : DialectDataTests { 10 | 11 | public SqlServerDialectDataTests() { 12 | _dialect = new SqlDialect(); 13 | } 14 | 15 | protected override string GetResultFor_Can_create_check_if_table_exists_sql() { 16 | return "SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'mytable'"; 17 | } 18 | 19 | protected override string GetResultFor_Can_generate_count_sql() { 20 | return "select count(*) from mytable"; 21 | } 22 | 23 | protected override string GetResultFor_Can_generate_select_sql_with_pagination(int skip, int to) { 24 | string sql = @"select * into #TempTable from ( 25 | select * ,ROW_NUMBER() over(order by aaa) AS rownum from ( 26 | select 'aaa' as aaa, * from ( 27 | SELECT TOP 2147483647 * from myTable 28 | )as t1 29 | )as t2 30 | ) as t3 31 | where rownum between {0} and {1} 32 | alter table #TempTable drop column aaa 33 | alter table #TempTable drop column rownum 34 | select * from #TempTable 35 | drop table #TempTable 36 | "; 37 | return String.Format(sql, skip + 1, skip + to); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/DialectTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using SharpData; 3 | 4 | namespace Sharp.Tests.Data.Databases { 5 | public abstract class DialectTests { 6 | protected string TABLE_NAME = "myTable"; 7 | protected Dialect _dialect; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Schema/MySqlDialectSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Databases.MySql; 3 | using Xunit; 4 | 5 | namespace Sharp.Tests.Databases.Mysql { 6 | 7 | public class MySqlDialectSchemaTests : DialectSchemaTests { 8 | 9 | public MySqlDialectSchemaTests() { 10 | _dialect = new MySqlDialect(); 11 | } 12 | 13 | protected override string[] GetResultFor_Can_create_table_sql() { 14 | return new[] { "create table myTable (id int not null auto_increment, name VARCHAR(255) not null, primary key(id))" }; 15 | } 16 | 17 | protected override string[] GetResultFor_Can_drop_table() { 18 | return new[] { "drop table myTable" }; 19 | } 20 | 21 | protected override string GetResultFor_Can_convert_column_to_sql__with_not_null() { 22 | return "col varchar(255) not null"; 23 | } 24 | 25 | protected override string GetResultFor_Can_convert_column_to_sql__with_primary_key() { 26 | //primary key is defined after all columns when creating table 27 | return "col varchar(255) not null"; 28 | } 29 | 30 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement() { 31 | return "col int not null auto_increment"; 32 | } 33 | 34 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement_and_primary_key() { 35 | //primary key is defined after all columns when creating table 36 | return "col int not null auto_increment"; 37 | } 38 | 39 | protected override string GetResultFor_Can_convert_column_to_sql__default_value() { 40 | return "col varchar(255) null default 'some string'"; 41 | } 42 | 43 | protected override string[] GetResultFor_Can_convert_column_to_values() { 44 | return new[] { 45 | "'foo'", 46 | "1", 47 | "1", 48 | "24.33", 49 | "'2009-01-20 12:30:00'" 50 | }; 51 | } 52 | 53 | protected override string GetResultFor_Can_add_comment_to_column() { 54 | throw new NotImplementedException(); 55 | } 56 | 57 | [Fact(Skip = "Not implemented yet. Pull requests welcome :)")] 58 | public override void Can_add_comment_to_column() { 59 | 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Schema/OracleDialectSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using SharpData; 4 | using SharpData.Databases.Oracle; 5 | 6 | namespace Sharp.Tests.Databases.Oracle { 7 | 8 | public class OracleDialectSchemaTests : DialectSchemaTests { 9 | public OracleDialectSchemaTests() { 10 | _dialect = new OracleDialect(); 11 | } 12 | 13 | 14 | protected override string[] GetResultFor_Can_create_table_sql() { 15 | return new [] { 16 | "create table myTable (id number(10) not null, name varchar2(255) not null)", 17 | "create sequence seq_mytable minvalue 1 maxvalue 999999999999999999999999999 start with 1 increment by 1 cache 20", 18 | "create or replace trigger \"tr_inc_mytable\" before insert on mytable for each row when (new.id is null) begin select seq_mytable.nextval into :new.id from dual; end tr_inc_mytable;", 19 | "alter table mytable add constraint pk_mytable primary key (id)" 20 | }; 21 | } 22 | 23 | protected override string[] GetResultFor_Can_drop_table() { 24 | return new [] { "drop table mytable cascade constraints", 25 | "begin execute immediate 'drop sequence seq_mytable'; exception when others then null; end;" }; 26 | } 27 | 28 | protected override string GetResultFor_Can_convert_column_to_sql__with_not_null() { 29 | return "col varchar2(255) not null"; 30 | } 31 | 32 | protected override string GetResultFor_Can_convert_column_to_sql__with_primary_key() { 33 | return "col varchar2(255) not null"; 34 | } 35 | 36 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement() { 37 | return "col number(10) not null"; 38 | } 39 | 40 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement_and_primary_key() { 41 | return "col number(10) not null"; 42 | } 43 | 44 | protected override string GetResultFor_Can_convert_column_to_sql__default_value() { 45 | return "col varchar2(255) default 'some string' null"; 46 | } 47 | 48 | protected override string[] GetResultFor_Can_convert_column_to_values() { 49 | return new[] { 50 | "'foo'", 51 | "1", 52 | "1", 53 | "24.33", 54 | "to_date('20/1/2009 12:30:0','dd/mm/yyyy hh24:mi:ss')" 55 | }; 56 | } 57 | 58 | protected override string GetResultFor_Can_add_comment_to_column() { 59 | return "COMMENT ON column myTable.col1 is 'this is a comment'"; 60 | } 61 | 62 | protected override string GetResutFor_Can_drop_index_sql() { 63 | return "drop index indexName"; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Schema/PostgreSqlDialectSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using SharpData.Databases.PostgreSql; 3 | 4 | namespace Sharp.Tests.Databases.PostgreSql { 5 | public class PostgreSqlDialectSchemaTests : DialectSchemaTests { 6 | public PostgreSqlDialectSchemaTests() { 7 | _dialect = new PostgreSqlDialect(); 8 | } 9 | 10 | protected override string[] GetResultFor_Can_create_table_sql() { 11 | return new[] { "create table myTable (id integer not null, name varchar(255) not null)", 12 | "create sequence seq_mytable increment 1 minvalue 1 maxvalue 9223372036854775807 start 1 cache 1", 13 | "alter table myTable alter column id set default nextval(\'seq_mytable\'::regclass)", 14 | "alter table mytable add constraint pk_mytable primary key (id)"}; 15 | } 16 | 17 | protected override string[] GetResultFor_Can_drop_table() { 18 | return new[] { "drop table mytable cascade", "drop sequence if exists seq_mytable cascade" }; 19 | } 20 | 21 | protected override string GetResultFor_Can_convert_column_to_sql__with_not_null() { 22 | return "col varchar(255) not null"; 23 | } 24 | 25 | protected override string GetResultFor_Can_convert_column_to_sql__with_primary_key() { 26 | return "col varchar(255) not null"; 27 | } 28 | 29 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement() { 30 | return "col integer not null"; 31 | } 32 | 33 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement_and_primary_key() { 34 | return "col integer not null"; 35 | } 36 | 37 | protected override string GetResultFor_Can_convert_column_to_sql__default_value() { 38 | return "col varchar(255) default 'some string' null"; 39 | } 40 | 41 | protected override string[] GetResultFor_Can_convert_column_to_values() { 42 | return new[] { 43 | "'foo'", 44 | "1", 45 | "true", 46 | "24.33", 47 | "'2009-01-20T12:30:00'" 48 | }; 49 | } 50 | 51 | protected override string GetResultFor_Can_add_comment_to_column() { 52 | return "COMMENT ON column myTable.col1 is 'this is a comment'"; 53 | } 54 | 55 | protected override string GetResutFor_Can_drop_index_sql() { 56 | return "drop index indexName"; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Schema/SqLiteDialectSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using SharpData.Databases.SqLite; 4 | 5 | namespace Sharp.Tests.Databases.SQLite { 6 | 7 | public class SqLiteDialectSchemaTests : DialectSchemaTests { 8 | public SqLiteDialectSchemaTests() { 9 | _dialect = new SqLiteDialect(); 10 | } 11 | 12 | protected override string[] GetResultFor_Can_create_table_sql() { 13 | return new[] {"create table myTable (id integer not null primary key autoincrement, name varchar(255) not null)"}; 14 | } 15 | 16 | protected override string[] GetResultFor_Can_drop_table() { 17 | return new [] {"drop table mytable"}; 18 | } 19 | 20 | protected override string GetResultFor_Can_convert_column_to_sql__with_not_null() { 21 | return "col varchar(255) not null"; 22 | } 23 | 24 | protected override string GetResultFor_Can_convert_column_to_sql__with_primary_key() { 25 | return "col varchar(255) not null primary key"; 26 | } 27 | 28 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement() { 29 | return "col integer not null primary key autoincrement"; 30 | } 31 | 32 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement_and_primary_key() { 33 | return "col integer not null primary key autoincrement"; 34 | } 35 | 36 | protected override string GetResultFor_Can_convert_column_to_sql__default_value() { 37 | return "col varchar(255) null default ('some string')"; 38 | } 39 | 40 | protected override string[] GetResultFor_Can_convert_column_to_values() { 41 | return new[] { 42 | "'foo'", 43 | "1", 44 | "true", 45 | "24.33", 46 | "2009-01-20T12:30:00" 47 | }; 48 | } 49 | 50 | protected override string GetResultFor_Can_add_comment_to_column() { 51 | return "foo"; 52 | } 53 | 54 | [Fact(Skip = "Not supported by SqLite")] 55 | public override void Can_add_comment_to_column() { 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /SharpData.Tests/Dialects/Schema/SqlServerDialectSchemaTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Xunit; 6 | using SharpData.Databases.SqlServer; 7 | 8 | namespace Sharp.Tests.Databases.SqlServer { 9 | public class SqlServerDialectSchemaTests : DialectSchemaTests { 10 | 11 | public SqlServerDialectSchemaTests() { 12 | _dialect = new SqlDialect(); 13 | } 14 | protected override string[] GetResultFor_Can_create_table_sql() { 15 | return new string[2] { 16 | "create table mytable (id integer not null identity(1,1), name nvarchar(255) not null)", 17 | "alter table mytable add constraint pk_mytable primary key (id)" 18 | }; 19 | } 20 | 21 | protected override string[] GetResultFor_Can_drop_table() { 22 | return new [] {"drop table myTable"}; 23 | } 24 | 25 | protected override string GetResultFor_Can_convert_column_to_sql__with_not_null() { 26 | return "col nvarchar(255) not null"; 27 | } 28 | 29 | protected override string GetResultFor_Can_convert_column_to_sql__with_primary_key() { 30 | return "col nvarchar(255) not null"; 31 | } 32 | 33 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement() { 34 | return "col integer not null identity(1,1)"; 35 | } 36 | 37 | protected override string GetResultFor_Can_convert_column_to_sql__autoIncrement_and_primary_key() { 38 | return "col integer not null identity(1,1)"; 39 | } 40 | 41 | protected override string GetResultFor_Can_convert_column_to_sql__default_value() { 42 | return "col nvarchar(255) null default ('some string')"; 43 | } 44 | 45 | protected override string[] GetResultFor_Can_convert_column_to_values() { 46 | return new[] { 47 | "'foo'", 48 | "1", 49 | "1", 50 | "24.33", 51 | "'2009-01-20T12:30:00'" 52 | }; 53 | } 54 | 55 | protected override string GetResultFor_Can_add_comment_to_column() { 56 | return "declare @currentuser sysname; select @currentuser = user_name(); execute sp_addextendedproperty 'ms_description','this is a comment','user',@currentuser,'table','mytable','column','col1'"; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SharpData.Tests/FilterTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SharpData; 6 | using SharpData.Schema; 7 | using Xunit; 8 | using SharpData.Fluent; 9 | 10 | namespace Sharp.Tests.Data { 11 | 12 | public class FilterTests { 13 | 14 | [Fact] 15 | public void Test() { 16 | IDataClient client = null; 17 | 18 | 19 | //client.Delete() 20 | // .From("table") 21 | // .Where 22 | // .Eq("asdf", 1).And 23 | // .Eq("asdf", 2).Or 24 | // .Lt("asdf", 5) 25 | // .DoIt(); 26 | 27 | //client.Select() 28 | // .AllColumns() 29 | // .From("") 30 | // .Where 31 | // .Eq("asdf", 1).Or 32 | // .Eq("asdf", 2) 33 | // .DoIt(); 34 | 35 | 36 | //client.Update.Table("table").SetColumns().ToValues(); 37 | 38 | //client.WithTable("table") 39 | // .WithAllRows 40 | // .Select(); 41 | 42 | //client.WithTable("table") 43 | // .Where 44 | // .Select(); 45 | 46 | //client.WithTable("table") 47 | // .AllRows 48 | // .SetColumns() 49 | // .ToValues(); 50 | 51 | //client.WithTable("table") 52 | // .WithAllRows 53 | // .Delete(); 54 | 55 | //client.WithTable("table") 56 | // .Insert 57 | // .IntoColumns() 58 | // .TheValues(); 59 | 60 | //Filter idEquals1AndNameEquals10 = Filter.Eq("Id", 1).And 61 | // .Eq("Col",3). 62 | 63 | //client.Select.From("table").Where(idEquals1); 64 | 65 | //Filter filter1 = Filter.Eq("asdf", 1); 66 | //Filter filter2 = Filter.Eq("asdf", 2); 67 | 68 | //Filter filter = Filter.And(filter1, filter2); 69 | 70 | //Filter filter3 = Filter.Eq("asdf", 1); 71 | //Filter filter4 = Filter.Eq("asdf", 2); 72 | 73 | //Filter filter = Filter.Or(filter3, filter4); 74 | 75 | 76 | 77 | 78 | //client.Insert.Into("tab").Columns("asdf").Values("asdf"); 79 | 80 | //client.Update.Table("asdf").SetColumns("").ToValues("asdf").Where(filter); 81 | 82 | 83 | //client.Delete 84 | // .From("tablex") 85 | // .Only.When.Column("id").Eq(1); 86 | 87 | //client.Delete 88 | // .From("tbx") 89 | // .Where( 90 | // Filter.Eq("c1",1).OrFilter( 91 | // Filter.Eq("c1",2).AndFilter( 92 | // Filter.Eq("c2",3).AndFilter( 93 | // Filter.Eq("c1",1).Or.Eq("c2",2) 94 | // ) 95 | // ) 96 | // ) 97 | // ); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /SharpData.Tests/Filters/CompareOperatorToSymbolTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Xunit; 6 | using SharpData.Filters; 7 | using SharpData.Query; 8 | 9 | namespace Sharp.Tests.Data.Filters { 10 | 11 | public class CompareOperatorToSymbolTests { 12 | 13 | [Fact] 14 | public void Should_return_equal_symbol() { 15 | Assert.Equal("=",CompareOperatorToSymbol.Get(CompareOperator.Equals)); 16 | } 17 | 18 | [Fact] 19 | public void Should_return_greater_symbol() { 20 | Assert.Equal(">", CompareOperatorToSymbol.Get(CompareOperator.GreaterThan)); 21 | } 22 | 23 | [Fact] 24 | public void Should_return_less_than_symbol() { 25 | Assert.Equal("<", CompareOperatorToSymbol.Get(CompareOperator.LessThan)); 26 | } 27 | 28 | [Fact] 29 | public void Should_return_greater_or_equal_symbol() { 30 | Assert.Equal(">=", CompareOperatorToSymbol.Get(CompareOperator.GreaterOrEqualThan)); 31 | } 32 | 33 | [Fact] 34 | public void Should_return_less_or_equal_symbol() { 35 | Assert.Equal("<=", CompareOperatorToSymbol.Get(CompareOperator.LessOrEqualThan)); 36 | } 37 | 38 | [Fact] 39 | public void Should_return_is_symbol() { 40 | Assert.Equal("is", CompareOperatorToSymbol.Get(CompareOperator.Is)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SharpData.Tests/Filters/FilterTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | using SharpData.Filters; 7 | using Xunit; 8 | using SharpData.Query; 9 | using FilterParameter = SharpData.Filters.FilterParameter; 10 | 11 | namespace Sharp.Tests.Data.Filters { 12 | 13 | 14 | public class FilterTests { 15 | 16 | [Fact] 17 | public void Can_create_eq_operator_with_colName_and_value() { 18 | TestFilterCondition(Filter.Eq("col1", 1), CompareOperator.Equals); 19 | } 20 | 21 | [Fact] 22 | public void Can_create_gt_operator_with_colName_and_value() { 23 | TestFilterCondition(Filter.Gt("col1", 1), CompareOperator.GreaterThan); 24 | } 25 | 26 | [Fact] 27 | public void Can_create_lt_operator_with_colName_and_value() { 28 | TestFilterCondition(Filter.Lt("col1", 1), CompareOperator.LessThan); 29 | } 30 | 31 | [Fact] 32 | public void Can_create_ge_operator_with_colName_and_value() { 33 | TestFilterCondition(Filter.Ge("col1", 1), CompareOperator.GreaterOrEqualThan); 34 | } 35 | 36 | [Fact] 37 | public void Can_create_le_operator_with_colName_and_value() { 38 | TestFilterCondition(Filter.Le("col1", 1), CompareOperator.LessOrEqualThan); 39 | } 40 | 41 | private void TestFilterCondition(Filter filter, CompareOperator compareOperator) { 42 | FilterCondition filterCondition = (FilterCondition) filter; 43 | 44 | Assert.Equal(compareOperator, filterCondition.CompareOperator); 45 | 46 | CheckFilterParameter(filterCondition.Left, "col1", FilterParameterType.Column); 47 | CheckFilterParameter(filterCondition.Right, 1, FilterParameterType.Value); 48 | } 49 | 50 | private void CheckFilterParameter(object filter, object value, FilterParameterType type) { 51 | FilterParameter filterParameter = (FilterParameter) filter; 52 | Assert.Equal(value, filterParameter.Value); 53 | Assert.Equal(type, filterParameter.FilterParameterType); 54 | } 55 | 56 | [Fact] 57 | public void Can_combine_two_filters_with_and() { 58 | 59 | Filter filter1 = Filter.Eq("col1", 1); 60 | Filter filter2 = Filter.Eq("col2", 2); 61 | 62 | Filter filter = Filter.And(filter1, filter2); 63 | 64 | Assert.Equal(filter1, filter.Left); 65 | Assert.Equal(filter2, filter.Right); 66 | Assert.Equal(LogicOperator.And, ((FilterLogic)filter).LogicOperator); 67 | } 68 | 69 | [Fact] 70 | public void Can_combine__filterA1_and_filterA2_with_filterB1_and_filterB2_using_or() { 71 | 72 | Filter filterA1 = Filter.Eq("colA1", 1); 73 | Filter filterA2 = Filter.Eq("colA2", 2); 74 | 75 | Filter filterA = Filter.And(filterA1, filterA2); 76 | 77 | Filter filterB1 = Filter.Eq("colB1", 3); 78 | Filter filterB2 = Filter.Eq("colB2", 4); 79 | 80 | Filter filterB = Filter.And(filterB1, filterB2); 81 | 82 | Filter filter = Filter.Or(filterA, filterB); 83 | 84 | Assert.Equal(filterA, filter.Left); 85 | Assert.Equal(filterB, filter.Right); 86 | Assert.Equal(LogicOperator.Or, ((FilterLogic)filter).LogicOperator); 87 | } 88 | 89 | [Fact] 90 | public void Can_get_all_parameters_from_filter_tree() { 91 | 92 | Filter filterA1 = Filter.Eq("colA1", 1); 93 | Filter filterA2 = Filter.Eq("colA2", 2); 94 | 95 | Filter filterA = Filter.And(filterA1, filterA2); 96 | 97 | Filter filterB1 = Filter.Eq("colB1", 3); 98 | Filter filterB2 = Filter.Eq("colB2", 4); 99 | 100 | Filter filterB = Filter.And(filterB1, filterB2); 101 | 102 | Filter filter = Filter.Or(filterA, filterB); 103 | 104 | object[] values = filter.GetAllValueParameters(); 105 | Assert.Equal(4, values.Count()); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /SharpData.Tests/MultipleTableTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Moq; 6 | using Xunit; 7 | using SharpData; 8 | using SharpData.Databases; 9 | using SharpData.Filters; 10 | 11 | namespace Sharp.Tests.Data { 12 | 13 | public class MultipleTableTests { 14 | 15 | private Mock _dialect; 16 | 17 | [Fact] 18 | public void Test() { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SharpData.Tests/Schema/ColumnTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Xunit; 5 | using System.Data; 6 | using SharpData.Schema; 7 | 8 | namespace Sharp.Tests.Data.Schema { 9 | 10 | public class ColumnTests { 11 | 12 | [Fact] 13 | public void Constructor_with_no_type_test() { 14 | var c = new Column("COL1"); 15 | Assert.Equal(DbType.String, c.Type); 16 | TestDefaults(c); 17 | } 18 | 19 | [Fact] 20 | public void Constructor_with_type_test() { 21 | var c = new Column("COL1", DbType.UInt32); 22 | Assert.Equal(DbType.UInt32, c.Type); 23 | TestDefaults(c); 24 | } 25 | 26 | [Fact] 27 | public void When_column_is_autoIncrement_it_is_also_not_null() { 28 | var c = new Column("COL1", DbType.UInt32); 29 | c.IsAutoIncrement = true; 30 | Assert.False(c.IsNullable); 31 | } 32 | 33 | [Fact] 34 | public void When_column_is_primary_key_it_is_also_not_null() { 35 | var c = new Column("COL1", DbType.UInt32); 36 | c.IsPrimaryKey = true; 37 | Assert.False(c.IsNullable); 38 | } 39 | 40 | protected void TestDefaults(Column c) { 41 | Assert.Null(c.DefaultValue); 42 | Assert.Equal("COL1", c.ColumnName); 43 | Assert.False(c.IsAutoIncrement); 44 | Assert.True(c.IsNullable); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SharpData.Tests/Schema/FluentColumnTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Xunit; 6 | using System.Data; 7 | using SharpData.Schema; 8 | 9 | namespace Sharp.Tests.Data.Schema { 10 | 11 | public class FluentColumnTest { 12 | 13 | [Fact] 14 | public void FluentCreationTests() { 15 | string col = "COL1"; 16 | 17 | FluentColumn f = Column.Binary(col); 18 | Assert.Equal(col, f.Object.ColumnName); 19 | Assert.Equal(DbType.Binary, f.Object.Type); 20 | 21 | f = Column.String(col); 22 | Assert.Equal(col, f.Object.ColumnName); 23 | Assert.Equal(DbType.String, f.Object.Type); 24 | 25 | f = Column.Int16(col); 26 | Assert.Equal(col, f.Object.ColumnName); 27 | Assert.Equal(DbType.Int16, f.Object.Type); 28 | 29 | f = Column.Int32(col); 30 | Assert.Equal(col, f.Object.ColumnName); 31 | Assert.Equal(DbType.Int32, f.Object.Type); 32 | 33 | f = Column.Int64(col); 34 | Assert.Equal(col, f.Object.ColumnName); 35 | Assert.Equal(DbType.Int64, f.Object.Type); 36 | 37 | f = Column.Boolean(col); 38 | Assert.Equal(col, f.Object.ColumnName); 39 | Assert.Equal(DbType.Boolean, f.Object.Type); 40 | 41 | f = Column.Binary(col); 42 | Assert.Equal(col, f.Object.ColumnName); 43 | Assert.Equal(DbType.Binary, f.Object.Type); 44 | 45 | f = Column.Date(col); 46 | Assert.Equal(col, f.Object.ColumnName); 47 | Assert.Equal(DbType.Date, f.Object.Type); 48 | 49 | f = Column.Decimal(col); 50 | Assert.Equal(col, f.Object.ColumnName); 51 | Assert.Equal(DbType.Decimal, f.Object.Type); 52 | 53 | f = Column.Single(col); 54 | Assert.Equal(col, f.Object.ColumnName); 55 | Assert.Equal(DbType.Single, f.Object.Type); 56 | 57 | f = Column.Double(col); 58 | Assert.Equal(col, f.Object.ColumnName); 59 | Assert.Equal(DbType.Double, f.Object.Type); 60 | 61 | f = Column.Guid(col); 62 | Assert.Equal(col, f.Object.ColumnName); 63 | Assert.Equal(DbType.Guid, f.Object.Type); 64 | 65 | f = Column.Clob(col); 66 | Assert.Equal(col, f.Object.ColumnName); 67 | Assert.Equal(DbType.String, f.Object.Type); 68 | Assert.Equal(Int32.MaxValue, f.Object.Size); 69 | } 70 | 71 | [Fact] 72 | public void Fluent_can_set_default_value() { 73 | Column c = Column.String("COL").DefaultValue("foo").Object; 74 | Assert.Equal("foo", c.DefaultValue); 75 | } 76 | 77 | [Fact] 78 | public void Fluent_can_set_autoIncrement() { 79 | Column c = Column.AutoIncrement("COL").Object; 80 | Assert.True(c.IsAutoIncrement); 81 | } 82 | 83 | [Fact] 84 | public void Fluent_can_set_is_not_null() { 85 | Column c = Column.String("COL").NotNull().Object; 86 | Assert.False(c.IsNullable); 87 | } 88 | 89 | [Fact] 90 | public void Fluent_can_set_comment() { 91 | string comment = "This is a comment"; 92 | Column c = Column.String("COL").Comment(comment).Object; 93 | Assert.Equal(comment, c.Comment); 94 | } 95 | 96 | [Fact] 97 | public void ComplexExample() { 98 | Column c = Column.String("COL").DefaultValue("foo").NotNull().AsPrimaryKey().Object; 99 | Assert.Equal("COL", c.ColumnName); 100 | Assert.Equal("foo", c.DefaultValue); 101 | Assert.True(c.IsPrimaryKey); 102 | Assert.False(c.IsNullable); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /SharpData.Tests/Schema/TableTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Xunit; 5 | using SharpData.Schema; 6 | 7 | namespace Sharp.Tests.Data.Schema { 8 | 9 | public class TableTests { 10 | 11 | [Fact] 12 | public void ConstructorTest() { 13 | var table = new Table("name"); 14 | Assert.Equal("name", table.Name); 15 | Assert.NotNull(table.Columns); 16 | Assert.Equal(0, table.Columns.Count); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SharpData.Tests/SharpData.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SharpData.Tests/Util/IntExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SharpData.Util; 6 | using Xunit; 7 | 8 | namespace Sharp.Tests.Data.Util { 9 | 10 | public class IntExtensionsTests { 11 | 12 | [Fact] 13 | public void BetweenTests() { 14 | int ten = 10; 15 | 16 | Assert.True(ten.Between(9, 11)); 17 | Assert.True(ten.Between(10, 10)); 18 | Assert.True(ten.Between(-1, 20)); 19 | Assert.False(ten.Between(11, 9)); 20 | Assert.False(ten.Between(-1, 0)); 21 | Assert.False(ten.Between(11, 12)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SharpData.Tests/WhereBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using SharpData; 3 | using SharpData.Databases; 4 | using SharpData.Filters; 5 | using Xunit; 6 | 7 | namespace Sharp.Tests.Data { 8 | 9 | public class WhereBuilderTests { 10 | private Mock _dialect; 11 | private WhereBuilder _whereBuilder; 12 | 13 | private string _wordWhere = "where"; 14 | 15 | private Filter _filter1; 16 | private Filter _filter2; 17 | private Filter _filter3; 18 | private Filter _filter4; 19 | 20 | 21 | public WhereBuilderTests() { 22 | _dialect = new Mock(); 23 | 24 | _dialect.Setup(p => p.WordWhere).Returns(_wordWhere); 25 | _dialect.Setup(p => p.GetParameterName(It.IsAny())) 26 | .Returns((int input) => ":par" + input); 27 | _dialect.Setup(p => p.WordNull).Returns("null"); 28 | 29 | _whereBuilder = new WhereBuilder(_dialect.Object, 0); 30 | 31 | _filter1 = CreateFilter(1); 32 | _filter2 = CreateFilter(2); 33 | _filter3 = CreateFilter(3); 34 | _filter4 = CreateFilter(4); 35 | } 36 | 37 | private Filter CreateFilter(int num) { 38 | return Filter.Eq("col" + num, num); 39 | } 40 | 41 | [Fact] 42 | public void Should_append_where_word() { 43 | var whereSql = _whereBuilder.Build(_filter1); 44 | Assert.True(whereSql.Contains(_wordWhere)); 45 | } 46 | 47 | [Fact] 48 | public void Can_generate_whereSql_with_one_condition() { 49 | string whereSql = _whereBuilder.Build(_filter1); 50 | 51 | AssertSql.AreEqual("where (col1 = :par0)", whereSql); 52 | } 53 | 54 | [Fact] 55 | public void Can_generate_where_with_logical_and() { 56 | Filter filter = Filter.And(_filter1, _filter2); 57 | 58 | string whereSql = _whereBuilder.Build(filter); 59 | 60 | AssertSql.AreEqual("where ((col1 = :par0) and (col2 = :par1))", whereSql); 61 | } 62 | 63 | [Fact] 64 | public void Can_generate_where_with_logical_or() { 65 | Filter filter = Filter.Or(_filter1, _filter2); 66 | 67 | string whereSql = _whereBuilder.Build(filter); 68 | 69 | AssertSql.AreEqual("where ((col1 = :par0) or (col2 = :par1))", whereSql); 70 | } 71 | 72 | [Fact] 73 | public void Can_generate_whereSql_with_composite_AND_and_OR() { 74 | Filter filterAnd1 = Filter.And(_filter1, _filter2); 75 | Filter filterAnd2 = Filter.And(_filter3, _filter4); 76 | 77 | Filter filter = Filter.Or(filterAnd1, filterAnd2); 78 | 79 | string whereSql = _whereBuilder.Build(filter); 80 | 81 | AssertSql.AreEqual("where (((col1 = :par0) and (col2 = :par1)) or ((col3 = :par2) and (col4 = :par3)))", whereSql); 82 | } 83 | 84 | [Fact] 85 | public void Can_generate_whereSql_with_null() { 86 | Filter filter = Filter.Eq("col1", null); 87 | string whereSql = _whereBuilder.Build(filter); 88 | AssertSql.AreEqual("where (col1 is null)", whereSql); 89 | } 90 | 91 | [Fact] 92 | public void Can_generate_whereSql_with_nulls_as_second_par() { 93 | Filter filter = Filter.Or(Filter.Eq("col1", "foo"), Filter.Eq("col1", null)); 94 | string whereSql = _whereBuilder.Build(filter); 95 | AssertSql.AreEqual("where ((col1 = :par0) Or (col1 is null))", whereSql); 96 | } 97 | 98 | [Fact] 99 | public void Can_generate_whereSql_with_null_as_first_par() { 100 | Filter filter = Filter.Or(Filter.Eq("col1", null), Filter.Eq("col1", "foo")); 101 | string whereSql = _whereBuilder.Build(filter); 102 | AssertSql.AreEqual("where ((col1 is null) Or (col1 = :par1))", whereSql); 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /SharpData.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26228.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpData", "SharpData\SharpData.csproj", "{114DCB49-5B78-4D87-A02D-918561D7799C}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpData.Sample.Core", "SharpData.Sample.Core\SharpData.Sample.Core.csproj", "{9D328685-EF5D-495C-91FB-6DA4C41E6148}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpData.Tests", "SharpData.Tests\SharpData.Tests.csproj", "{F20DCDED-B12F-4F7A-A775-89DFC91DCCBD}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpData.Tests.Integration", "SharpData.Tests.Integration\SharpData.Tests.Integration.csproj", "{91821AFF-E056-4556-930F-130B108C6E7C}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpData.Sample.NetFull", "SharpData.Sample.NetFull\SharpData.Sample.NetFull.csproj", "{0802E465-BA2F-4F06-88DF-B8A833752EF8}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {114DCB49-5B78-4D87-A02D-918561D7799C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {114DCB49-5B78-4D87-A02D-918561D7799C}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {114DCB49-5B78-4D87-A02D-918561D7799C}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {114DCB49-5B78-4D87-A02D-918561D7799C}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {9D328685-EF5D-495C-91FB-6DA4C41E6148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {9D328685-EF5D-495C-91FB-6DA4C41E6148}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {9D328685-EF5D-495C-91FB-6DA4C41E6148}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {9D328685-EF5D-495C-91FB-6DA4C41E6148}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {F20DCDED-B12F-4F7A-A775-89DFC91DCCBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {F20DCDED-B12F-4F7A-A775-89DFC91DCCBD}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {F20DCDED-B12F-4F7A-A775-89DFC91DCCBD}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {F20DCDED-B12F-4F7A-A775-89DFC91DCCBD}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {91821AFF-E056-4556-930F-130B108C6E7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {91821AFF-E056-4556-930F-130B108C6E7C}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {91821AFF-E056-4556-930F-130B108C6E7C}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {91821AFF-E056-4556-930F-130B108C6E7C}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {0802E465-BA2F-4F06-88DF-B8A833752EF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {0802E465-BA2F-4F06-88DF-B8A833752EF8}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {0802E465-BA2F-4F06-88DF-B8A833752EF8}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {0802E465-BA2F-4F06-88DF-B8A833752EF8}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {4F810F41-7C16-4149-ABB5-09224398F2CE} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /SharpData/DataReaderToResultSetMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | 5 | namespace SharpData { 6 | public class DataReaderToResultSetMapper { 7 | 8 | public static ResultSet Map(IDataReader dr) { 9 | var numberOfColumns = dr.FieldCount; 10 | var colNames = GetColumnNames(dr, numberOfColumns); 11 | var table = new ResultSet(colNames); 12 | while (dr.Read()) { 13 | MapRow(dr, numberOfColumns, table); 14 | } 15 | return table; 16 | } 17 | 18 | private static void MapRow(IDataReader dr, int numberOfColumns, ResultSet table) { 19 | var row = new object[numberOfColumns]; 20 | for (var i = 0; i < numberOfColumns; i++) { 21 | row[i] = (DBNull.Value.Equals(dr[i])) ? null : dr[i]; 22 | } 23 | table.AddRow(row); 24 | } 25 | 26 | private static string[] GetColumnNames(IDataReader dr, int numberOfColumns) { 27 | var colNames = new List(); 28 | for (var i = 0; i < numberOfColumns; i++) { 29 | colNames.Add(dr.GetName(i)); 30 | } 31 | return colNames.ToArray(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SharpData/Databases/DataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using System.Data.Common; 4 | 5 | namespace SharpData.Databases { 6 | public abstract class DataProvider : IDataProvider { 7 | protected DbProviderFactory DbProviderFactory { get; } 8 | public abstract DbProviderType Name { get; } 9 | public abstract DatabaseKind DatabaseKind { get; } 10 | 11 | protected DataProvider(DbProviderFactory dbProviderFactory) { 12 | DbProviderFactory = dbProviderFactory; 13 | } 14 | 15 | public virtual IDbConnection GetConnection() { 16 | return DbProviderFactory.CreateConnection(); 17 | } 18 | 19 | public virtual void ConfigCommand(IDbCommand command, object[] parameters, bool isBulk) { } 20 | 21 | public DbParameter GetParameter() { 22 | return DbProviderFactory.CreateParameter(); 23 | } 24 | 25 | public virtual DbParameter GetParameter(In parameter, bool isBulk) { 26 | return GetParameter(); 27 | } 28 | 29 | public virtual DbParameter GetParameterCursor() { 30 | return DbProviderFactory.CreateParameter(); 31 | } 32 | 33 | public virtual DatabaseException CreateSpecificException(Exception exception, string sql) { 34 | return new DatabaseException(exception.Message, exception, sql); 35 | } 36 | 37 | public virtual string GetPreCommand() { 38 | return null; 39 | } 40 | 41 | public virtual string GetOnErrorCommand() { 42 | return null; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /SharpData/Databases/DatabaseKind.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Databases { 2 | public enum DatabaseKind { 3 | Oracle, 4 | SqlServer, 5 | MySql, 6 | SqLite, 7 | OleDb, 8 | PostgreSql 9 | } 10 | } -------------------------------------------------------------------------------- /SharpData/Databases/DbProviderType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace SharpData.Databases { 6 | public enum DbProviderType { 7 | OracleManaged, 8 | OracleOdp, 9 | MySql, 10 | SqlServer, 11 | SqLite, 12 | OleDb, 13 | PostgreSql 14 | } 15 | public static class DbProviderTypeExtensions { 16 | public static string GetProviderName(this DbProviderType type) { 17 | switch (type) { 18 | case DbProviderType.OracleManaged: 19 | return "Oracle.ManagedDataAccess.Client"; 20 | case DbProviderType.OracleOdp: 21 | return "Oracle.DataAccess.Client"; 22 | case DbProviderType.MySql: 23 | return "MySql.Data.MySqlClient"; 24 | case DbProviderType.SqlServer: 25 | return "System.Data.SqlClient"; 26 | case DbProviderType.SqLite: 27 | return "Microsoft.Data.Sqlite"; 28 | case DbProviderType.OleDb: 29 | return "System.Data.OleDb"; 30 | case DbProviderType.PostgreSql: 31 | return "Npgsql"; 32 | default: 33 | throw new ArgumentOutOfRangeException(nameof(type), type, null); 34 | } 35 | } 36 | 37 | public static DbProviderType GetDbProviderByNamespace(string name) 38 | { 39 | if (string.Equals(name, DbProviderType.OracleManaged.GetProviderName(), StringComparison.OrdinalIgnoreCase)) 40 | return DbProviderType.OracleManaged; 41 | if (string.Equals(name, DbProviderType.OracleOdp.GetProviderName(), StringComparison.OrdinalIgnoreCase)) 42 | return DbProviderType.OracleOdp; 43 | if (string.Equals(name, DbProviderType.MySql.GetProviderName(), StringComparison.OrdinalIgnoreCase)) 44 | return DbProviderType.MySql; 45 | if (string.Equals(name, DbProviderType.SqlServer.GetProviderName(), StringComparison.OrdinalIgnoreCase)) 46 | return DbProviderType.SqlServer; 47 | if (string.Equals(name, DbProviderType.SqLite.GetProviderName(), StringComparison.OrdinalIgnoreCase)) 48 | return DbProviderType.SqLite; 49 | if (string.Equals(name, DbProviderType.OleDb.GetProviderName(), StringComparison.OrdinalIgnoreCase)) 50 | return DbProviderType.OleDb; 51 | if (string.Equals(name, DbProviderType.PostgreSql.GetProviderName(), StringComparison.OrdinalIgnoreCase)) 52 | return DbProviderType.PostgreSql; 53 | throw new ArgumentOutOfRangeException(nameof(name), name, null); 54 | } 55 | 56 | public static List GetAll() { 57 | return Enum.GetValues(typeof(DbProviderType)) 58 | .Cast() 59 | .ToList(); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /SharpData/Databases/IDbTypeMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SharpData.Databases { 7 | public interface IDbTypeMap { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SharpData/Databases/MySql/MySqlDataClient.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Databases.MySql { 2 | public class MySqlDataClient : DataClient { 3 | public MySqlDataClient(IDatabase database, Dialect dialect) : base(database, dialect) { 4 | } 5 | } 6 | } -------------------------------------------------------------------------------- /SharpData/Databases/MySql/MySqlDbFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.MySql { 4 | public class MySqlDbFactory : DbFactory { 5 | public MySqlDbFactory(DbProviderFactory dbProviderFactory, string connectionString) 6 | : base(dbProviderFactory, connectionString) { 7 | } 8 | 9 | public override IDataProvider CreateDataProvider() { 10 | return new MySqlProvider(DbProviderFactory); 11 | } 12 | 13 | public override Dialect CreateDialect() { 14 | return new MySqlDialect(); 15 | } 16 | 17 | public override IDataClient CreateDataClient() { 18 | return new MySqlDataClient(CreateDatabase(), CreateDialect()); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /SharpData/Databases/MySql/MySqlProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Common; 3 | using System.Reflection; 4 | using SharpData.Exceptions; 5 | using SharpData.Util; 6 | 7 | namespace SharpData.Databases.MySql { 8 | public class MySqlProvider : DataProvider { 9 | public MySqlProvider(DbProviderFactory dbProviderFactory) : base(dbProviderFactory) { 10 | } 11 | 12 | public override DbProviderType Name => DbProviderType.MySql; 13 | public override DatabaseKind DatabaseKind => DatabaseKind.MySql; 14 | 15 | public override DatabaseException CreateSpecificException(Exception exception, string sql) { 16 | var numberProp = exception.GetType().GetProperty("Number", ReflectionHelper.NoRestrictions); 17 | if (numberProp == null) { 18 | return base.CreateSpecificException(exception, sql); 19 | } 20 | var number = numberProp.GetValue(exception) as int?; 21 | if (number == 1075) { 22 | return new NotSupportedByDatabaseException( 23 | "Mysql databases require autoincrement columns to be the primary key", exception, sql); 24 | } 25 | return base.CreateSpecificException(exception, sql); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /SharpData/Databases/Oracle/OracleDataClient.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Databases.Oracle { 2 | public class OracleDataClient : DataClient { 3 | public OracleDataClient(IDatabase database, Dialect dialect) : base(database, dialect) { 4 | } 5 | } 6 | } -------------------------------------------------------------------------------- /SharpData/Databases/Oracle/OracleManagedDbFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.Oracle { 4 | public class OracleManagedDbFactory : DbFactory { 5 | public OracleManagedDbFactory(DbProviderFactory dbProviderFactory, string connectionString) 6 | : base(dbProviderFactory, connectionString) { 7 | } 8 | 9 | public override IDataProvider CreateDataProvider() { 10 | return new OracleManagedProvider(DbProviderFactory); 11 | } 12 | 13 | public override Dialect CreateDialect() { 14 | return new OracleDialect(); 15 | } 16 | 17 | public override IDataClient CreateDataClient() { 18 | return new OracleDataClient(CreateDatabase(), CreateDialect()); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /SharpData/Databases/Oracle/OracleManagedProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.Oracle { 4 | public class OracleManagedProvider : OracleOdpProvider { 5 | private static OracleReflectionCache _reflectionCache = new OracleReflectionCache(); 6 | protected override string OracleDbTypeEnumName => "Oracle.ManagedDataAccess.Client.OracleDbType"; 7 | public override OracleReflectionCache ReflectionCache => _reflectionCache; 8 | public override DbProviderType Name { get; } = DbProviderType.OracleManaged; 9 | public OracleManagedProvider(DbProviderFactory dbProviderFactory) : base(dbProviderFactory) {} 10 | } 11 | } -------------------------------------------------------------------------------- /SharpData/Databases/Oracle/OracleOdpDbFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.Oracle { 4 | public class OracleOdpDbFactory : OracleManagedDbFactory { 5 | public OracleOdpDbFactory(DbProviderFactory dbProviderFactory, string connectionString) 6 | : base(dbProviderFactory, connectionString) { 7 | } 8 | 9 | public override IDataProvider CreateDataProvider() { 10 | return new OracleOdpProvider(DbProviderFactory); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /SharpData/Databases/Oracle/OracleReflectionCache.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace SharpData.Databases.Oracle { 4 | public class OracleReflectionCache { 5 | public bool IsCached { get; set; } 6 | public PropertyInfo PropParameterDbType { get; set; } 7 | public PropertyInfo PropBindByName { get; set; } 8 | public PropertyInfo PropArrayBindCount { get; set; } 9 | public object DbTypeRefCursor { get; set; } 10 | public object DbTypeBlob { get; set; } 11 | public object DbTypeDate { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /SharpData/Databases/PostgreSql/PostgreDbFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.PostgreSql { 4 | public class PostgreDbFactory : DbFactory { 5 | public PostgreDbFactory(DbProviderFactory dbProviderFactory, string connectionString) : 6 | base(dbProviderFactory, connectionString) { } 7 | public override IDataProvider CreateDataProvider() { 8 | return new PostgreSqlProvider(DbProviderFactory); 9 | } 10 | 11 | public override Dialect CreateDialect() { 12 | return new PostgreSqlDialect(); 13 | } 14 | 15 | public override IDataClient CreateDataClient() { 16 | return new PostgreSqlDataClient(CreateDatabase(), CreateDialect()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SharpData/Databases/PostgreSql/PostgreSqlConstraintsDialect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Schema; 3 | using Sharp.Util; 4 | 5 | namespace SharpData.Databases.PostgreSql { 6 | public class PostgreSqlConstraintsDialect { 7 | public string GetForeignKeySql(string fkName, string table, string column, string referencingTable, string referencingColumn, OnDelete onDelete) { 8 | string onDeleteSql; 9 | switch (onDelete) { 10 | case OnDelete.Cascade: 11 | onDeleteSql = "ON DELETE CASCADE"; 12 | break; 13 | case OnDelete.SetNull: 14 | onDeleteSql = "ON DELETE SET NULL"; 15 | break; 16 | default: 17 | onDeleteSql = ""; 18 | break; 19 | } 20 | 21 | return String.Format("ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}) {5}", 22 | table, 23 | fkName, 24 | column, 25 | referencingTable, 26 | referencingColumn, 27 | onDeleteSql); 28 | } 29 | 30 | public string GetUniqueKeySql(string ukName, string table, string[] columnNames) { 31 | return String.Format("ALTER TABLE {0} ADD CONSTRAINT {1} UNIQUE ({2})", table, ukName, String.Join(",", columnNames)); 32 | } 33 | 34 | public string GetDropUniqueKeySql(string uniqueKeyName, string tableName) { 35 | return String.Format("ALTER TABLE {0} DROP CONSTRAINT {1}", tableName, uniqueKeyName); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /SharpData/Databases/PostgreSql/PostgreSqlDataClient.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Databases.PostgreSql { 2 | public class PostgreSqlDataClient : DataClient { 3 | public PostgreSqlDataClient(IDatabase database, Dialect dialect) : base(database, dialect) { } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /SharpData/Databases/PostgreSql/PostgreSqlDbTypesDialect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using SharpData.Exceptions; 4 | 5 | namespace SharpData.Databases.PostgreSql { 6 | public class PostgreSqlDbTypesDialect { 7 | public static string GetDbTypeString(DbType type, int precision) { 8 | switch (type) { 9 | case DbType.AnsiString: 10 | case DbType.String: 11 | if (precision <= 0) 12 | return "VARCHAR(255)"; 13 | if (precision < 10485760) 14 | return String.Format("VARCHAR({0})", precision); 15 | return "TEXT"; 16 | case DbType.Binary: 17 | return "BYTEA"; 18 | case DbType.Boolean: 19 | return "BOOL"; 20 | case DbType.Currency: 21 | return "MONEY"; 22 | case DbType.Date: 23 | case DbType.DateTime: 24 | return "TIMESTAMP"; 25 | case DbType.Decimal: 26 | return precision <= 0 ? "NUMERIC(19,5)" : String.Format("NUMERIC(19,{0})", precision); 27 | case DbType.Double: 28 | return "FLOAT8"; 29 | case DbType.Guid: 30 | return "UUID"; 31 | case DbType.Int16: 32 | return "SMALLINT"; 33 | case DbType.Int32: 34 | return "INTEGER"; 35 | case DbType.Int64: 36 | return "BIGINT"; 37 | case DbType.Single: 38 | return "FLOAT4"; 39 | case DbType.Time: 40 | return "TIME"; 41 | case DbType.AnsiStringFixedLength: 42 | case DbType.StringFixedLength: 43 | return precision <= 0 ? "CHAR(255)" : String.Format("CHAR({0})", precision); 44 | case DbType.Xml: 45 | return "XML"; 46 | case DbType.DateTimeOffset: 47 | return "TIMESTAMPTZ"; 48 | default: 49 | throw new DataTypeNotAvailableException(String.Format("The type {0} is no available for postgreSql", type)); 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /SharpData/Databases/PostgreSql/PostgreSqlProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Common; 3 | using SharpData.Exceptions; 4 | 5 | namespace SharpData.Databases.PostgreSql { 6 | public class PostgreSqlProvider : DataProvider { 7 | private const string SavepointId = "PostgreSqlId"; 8 | 9 | public PostgreSqlProvider(DbProviderFactory dbProviderFactory) : base(dbProviderFactory) { } 10 | public override DbProviderType Name => DbProviderType.PostgreSql; 11 | public override DatabaseKind DatabaseKind => DatabaseKind.PostgreSql; 12 | 13 | public override DatabaseException CreateSpecificException(Exception exception, string sql) { 14 | if (exception.Message.Contains("42P01")) { 15 | return new TableNotFoundException(exception.Message, exception, sql); 16 | } 17 | if (exception.Message.Contains("23505")) { 18 | return new UniqueConstraintException(exception.Message, exception, sql); 19 | } 20 | return base.CreateSpecificException(exception, sql); 21 | } 22 | 23 | public override string GetPreCommand() { 24 | return String.Format("SAVEPOINT {0}", SavepointId); 25 | } 26 | 27 | public override string GetOnErrorCommand() { 28 | return String.Format("ROLLBACK TO {0}", SavepointId); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SharpData/Databases/PostgreSql/PostgreSqlTableDialect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using SharpData.Schema; 5 | 6 | namespace SharpData.Databases.PostgreSql { 7 | public class PostgreSqlTableDialect { 8 | public static string SequencePrefix = "SEQ_"; 9 | public static string PrimaryKeyPrefix = "PK_"; 10 | 11 | public string[] GetCreateTableSqls(Table table, Func getColumnToSqlWhenCreate, Func getPrimaryKeySql) { 12 | var sqls = new List(); 13 | var primaryKeyColumns = new List(); 14 | var tableName = table.Name; 15 | Column autoIncrementColumn = null; 16 | 17 | //create table 18 | var sb = new StringBuilder(); 19 | sb.Append("CREATE TABLE ").Append(table.Name).AppendLine(" ("); 20 | 21 | var size = table.Columns.Count; 22 | for (var i = 0; i < size; i++) { 23 | var column = table.Columns[i]; 24 | 25 | sb.Append(getColumnToSqlWhenCreate(column)); 26 | if (i != size - 1) { 27 | sb.AppendLine(","); 28 | } 29 | 30 | if (column.IsAutoIncrement) { 31 | autoIncrementColumn = column; 32 | } 33 | if (column.IsPrimaryKey) { 34 | primaryKeyColumns.Add(column.ColumnName); 35 | } 36 | } 37 | sb.AppendLine(")"); 38 | sqls.Add(sb.ToString()); 39 | 40 | SetAutoIncrementColumn(autoIncrementColumn, tableName, sqls); 41 | SetPrimaryKey(primaryKeyColumns, sqls, tableName, getPrimaryKeySql); 42 | 43 | return sqls.ToArray(); 44 | } 45 | 46 | public string[] GetDropTableSqls(string tableName) { 47 | return new[] { 48 | String.Format("DROP TABLE {0} CASCADE", tableName), 49 | String.Format("DROP SEQUENCE IF EXISTS {0}{1} CASCADE", SequencePrefix, tableName) 50 | }; 51 | } 52 | 53 | private void SetPrimaryKey(List primaryKeyColumns, ICollection sqls, string tableName, Func getPrimaryKeySql) { 54 | if (primaryKeyColumns.Count > 0) { 55 | sqls.Add(getPrimaryKeySql(tableName, String.Format("{0}{1}", PrimaryKeyPrefix, tableName), primaryKeyColumns.ToArray())); 56 | } 57 | } 58 | 59 | private static void SetAutoIncrementColumn(Column autoIncrementColumn, string tableName, ICollection sqls) { 60 | if (autoIncrementColumn == null) { 61 | return; 62 | } 63 | var sequenceName = SequencePrefix + tableName; 64 | sqls.Add(String.Format("CREATE SEQUENCE {0} INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1", sequenceName)); 65 | sqls.Add(String.Format("ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT NEXTVAL(\'{2}\'::REGCLASS)", tableName, autoIncrementColumn.ColumnName, sequenceName)); 66 | } 67 | 68 | public string GetRenameTableSql(string tableName, string newTableName) { 69 | return String.Format("ALTER TABLE {0} RENAME TO {1}", tableName, newTableName); 70 | } 71 | 72 | public string GetTableExistsSql(string tableName) { 73 | return String.Format("SELECT COUNT(relname) FROM pg_class WHERE relname = '{0}'", tableName); 74 | } 75 | 76 | public string GetAddCommentToTableSql(string tableName, string comment) { 77 | return String.Format("COMMENT ON TABLE {0} IS '{1}'", tableName, comment); 78 | } 79 | 80 | public string GetRemoveCommentToTableSql(string tableName) { 81 | return String.Format("COMMENT ON TABLE {0} IS ''", tableName); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /SharpData/Databases/PostgreSql/SqlColumnStructure.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Databases.PostgreSql { 2 | internal class SqlColumnStructure { 3 | public string Type { get; set; } 4 | public string Nullable { get; set; } 5 | public string Default { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /SharpData/Databases/SelectBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SharpData.Filters; 3 | using SharpData.Schema; 4 | 5 | namespace SharpData.Databases { 6 | public class SelectBuilder { 7 | private Dialect _dialect; 8 | private string[] _tables; 9 | private string[] _columns; 10 | 11 | public Filter Filter { get; set; } 12 | public OrderBy[] OrderBys { get; set; } 13 | public int Skip { get; set; } 14 | public int Take { get; set; } 15 | 16 | public In[] Parameters { get; set; } 17 | 18 | public bool HasFilter { get; protected set; } 19 | 20 | private string _select; 21 | 22 | public SelectBuilder(Dialect dialect, string[] tables, string[] columns) { 23 | _dialect = dialect; 24 | _tables = tables; 25 | _columns = columns; 26 | 27 | Parameters = new In[0]; 28 | } 29 | 30 | public string Build() { 31 | _select = _dialect.GetSelectSql(_tables, _columns); 32 | ApplyFilter(); 33 | ApplyOrderBy(); 34 | ApplySkipTakeToSql(); 35 | return _select; 36 | } 37 | 38 | private void ApplyFilter() { 39 | if (Filter != null) { 40 | HasFilter = true; 41 | 42 | var whereSql = _dialect.GetWhereSql(Filter, 0); 43 | var pars = Filter.GetAllValueParameters(); 44 | Parameters = _dialect.ConvertToNamedParameters(0, pars); 45 | _select += " " + whereSql; 46 | } 47 | } 48 | 49 | private void ApplyOrderBy() { 50 | if (OrderBys != null) { 51 | _select += " " + _dialect.GetOrderBySql(OrderBys); 52 | } 53 | } 54 | 55 | protected string ApplySkipTakeToSql() { 56 | if (Skip > 0 || Take > 0) { 57 | _select = _dialect.WrapSelectSqlWithPagination(_select, Skip, Take); 58 | } 59 | return _select; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /SharpData/Databases/SqLite/SQLiteProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.SqLite { 4 | public class SqLiteProvider : DataProvider { 5 | public SqLiteProvider(DbProviderFactory dbProviderFactory) : base(dbProviderFactory) { 6 | } 7 | 8 | public override DbProviderType Name => DbProviderType.SqLite; 9 | public override DatabaseKind DatabaseKind => DatabaseKind.Oracle; 10 | } 11 | } -------------------------------------------------------------------------------- /SharpData/Databases/SqLite/SqLiteDataClient.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Databases.SqLite { 2 | public class SqLiteDataClient : DataClient { 3 | public SqLiteDataClient(IDatabase database, Dialect dialect) 4 | : base(database, dialect) { 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /SharpData/Databases/SqLite/SqLiteDbFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.SqLite { 4 | public class SqLiteDbFactory : DbFactory { 5 | public SqLiteDbFactory(DbProviderFactory dbProviderFactory, string connectionString) 6 | : base(dbProviderFactory, connectionString) { 7 | } 8 | 9 | public override IDataProvider CreateDataProvider() { 10 | return new SqLiteProvider(DbProviderFactory); 11 | } 12 | 13 | public override Dialect CreateDialect() { 14 | return new SqLiteDialect(); 15 | } 16 | 17 | public override IDataClient CreateDataClient() { 18 | return new SqLiteDataClient(CreateDatabase(), CreateDialect()); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /SharpData/Databases/SqlServer/OleDbDbFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.SqlServer { 4 | public class OleDbDbFactory : SqlServerDbFactory { 5 | public OleDbDbFactory(DbProviderFactory dbProviderFactory, string connectionString) 6 | : base(dbProviderFactory, connectionString) { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /SharpData/Databases/SqlServer/SqlProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | using System.Reflection; 3 | using SharpData.Exceptions; 4 | using SharpData.Util; 5 | 6 | namespace SharpData.Databases.SqlServer { 7 | public class SqlProvider : DataProvider { 8 | public SqlProvider(DbProviderFactory dbProviderFactory) : base(dbProviderFactory) { 9 | } 10 | 11 | public override DbProviderType Name => DbProviderType.SqlServer; 12 | 13 | public override DatabaseKind DatabaseKind => DatabaseKind.SqlServer; 14 | 15 | public override DatabaseException CreateSpecificException(System.Exception exception, string sql) { 16 | var numberProp = exception.GetType().GetProperty("Number", ReflectionHelper.NoRestrictions); 17 | if(numberProp == null) { 18 | return base.CreateSpecificException(exception, sql); 19 | } 20 | var number = numberProp.GetValue(exception) as int?; 21 | if(number == 208) { 22 | return new TableNotFoundException(exception.Message, exception, sql); 23 | } 24 | if (number == 2627) { 25 | return new UniqueConstraintException(exception.Message, exception, sql); 26 | } 27 | return base.CreateSpecificException(exception, sql); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SharpData/Databases/SqlServer/SqlServerDataClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData.Databases.SqlServer { 4 | public class SqlServerDataClient : DataClient { 5 | public SqlServerDataClient(IDatabase database, Dialect dialect) 6 | : base(database, dialect) { 7 | } 8 | 9 | public override void RemoveColumn(string tableName, string columnName) { 10 | string[] sqls = Dialect.GetDropColumnSql(tableName, columnName); 11 | object defaultConstraintName = Database.QueryScalar(sqls[0]); 12 | if (defaultConstraintName != null) { 13 | Database.ExecuteSql(String.Format(sqls[1], defaultConstraintName)); 14 | } 15 | Database.ExecuteSql(sqls[2]); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /SharpData/Databases/SqlServer/SqlServerDbFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData.Databases.SqlServer { 4 | public class SqlServerDbFactory : DbFactory { 5 | public SqlServerDbFactory(DbProviderFactory dbProviderFactory, string connectionString) 6 | : base(dbProviderFactory, connectionString) { 7 | } 8 | 9 | public override IDataProvider CreateDataProvider() { 10 | return new SqlProvider(DbProviderFactory); 11 | } 12 | 13 | public override Dialect CreateDialect() { 14 | return new SqlDialect(); 15 | } 16 | 17 | public override IDataClient CreateDataClient() { 18 | return new SqlServerDataClient(CreateDatabase(), CreateDialect()); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /SharpData/Databases/WhereBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using SharpData.Filters; 3 | using SharpData.Query; 4 | 5 | namespace SharpData.Databases { 6 | public class WhereBuilder { 7 | 8 | private StringBuilder _builder = new StringBuilder(); 9 | private Dialect _dialect; 10 | private int _numValues; 11 | private int _parameterStartIndex; 12 | 13 | public WhereBuilder(Dialect dialect, int parameterStartIndex) { 14 | _dialect = dialect; 15 | _parameterStartIndex = parameterStartIndex; 16 | } 17 | 18 | public virtual string Build(Filter filter) { 19 | AppendWordWhere(); 20 | BuildRecursive(filter); 21 | return _builder.ToString(); 22 | } 23 | 24 | private void BuildRecursive(Filter filter) { 25 | if (filter is FilterCondition) { 26 | AddFilterParameter((FilterCondition)filter); 27 | return; 28 | } 29 | OpenParentesis(); 30 | BuildRecursive((Filter)filter.Left); 31 | AddLogicOperator(filter); 32 | BuildRecursive((Filter)filter.Right); 33 | CloseParentesis(); 34 | } 35 | 36 | private void AddLogicOperator(Filter filter) { 37 | AddSpace(); 38 | var filterLogic = filter as FilterLogic; 39 | _builder.Append(LogicOperatorToSymbol.Get(filterLogic.LogicOperator)); 40 | AddSpace(); 41 | } 42 | 43 | private void AddFilterParameter(FilterCondition filter) { 44 | OpenParentesis(); 45 | AppendParameter(filter.Left); 46 | AppendCompareOperator(filter); 47 | AppendParameter(filter.Right); 48 | CloseParentesis(); 49 | } 50 | 51 | private void AppendParameter(object parameter) { 52 | var filterParameter = (FilterParameter)parameter; 53 | if(filterParameter.FilterParameterType == FilterParameterType.Column) { 54 | _builder.Append(filterParameter.Value); 55 | } 56 | else { 57 | string value = filterParameter.ValueIsNullOrDBNull ? 58 | _dialect.WordNull : 59 | _dialect.GetParameterName(_numValues + _parameterStartIndex); 60 | _builder.Append(value); 61 | _numValues++; 62 | } 63 | } 64 | 65 | private void AppendCompareOperator(Filter filter) { 66 | var filterCondition = (FilterCondition) filter; 67 | var compareOperator = ChangeCompareOperatorToIsWhenParameterValueIsNull(filterCondition); 68 | AddSpace(); 69 | _builder.Append(CompareOperatorToSymbol.Get(compareOperator)); 70 | AddSpace(); 71 | } 72 | 73 | private static CompareOperator ChangeCompareOperatorToIsWhenParameterValueIsNull(FilterCondition filterCondition) { 74 | var parameter = filterCondition.Right as FilterParameter; 75 | if (parameter == null || 76 | parameter.FilterParameterType != FilterParameterType.Value || 77 | !parameter.ValueIsNullOrDBNull 78 | ) { 79 | return filterCondition.CompareOperator; 80 | } 81 | return CompareOperator.Is; 82 | } 83 | 84 | private void OpenParentesis() { 85 | _builder.Append("("); 86 | } 87 | 88 | private void CloseParentesis() { 89 | _builder.Append(")"); 90 | } 91 | 92 | private void AddSpace() { 93 | _builder.Append(" "); 94 | } 95 | 96 | private void AppendWordWhere() { 97 | _builder.Append(_dialect.WordWhere).Append(" "); 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /SharpData/DbFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Common; 3 | 4 | namespace SharpData { 5 | public abstract class DbFactory { 6 | public string ConnectionString { get; set; } 7 | public DbProviderFactory DbProviderFactory { get; set; } 8 | 9 | protected DbFactory(DbProviderFactory dbProviderFactory, string connectionString) { 10 | ConnectionString = connectionString; 11 | DbProviderFactory = dbProviderFactory; 12 | } 13 | 14 | public abstract IDataProvider CreateDataProvider(); 15 | public virtual IDatabase CreateDatabase() { 16 | return new Database(CreateDataProvider(), ConnectionString); 17 | } 18 | public abstract Dialect CreateDialect(); 19 | public abstract IDataClient CreateDataClient(); 20 | } 21 | } -------------------------------------------------------------------------------- /SharpData/ExceptionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace SharpData { 5 | public static class ExceptionHelper { 6 | 7 | public static string GetAllErrors(Exception ex) { 8 | var allErrors = new StringBuilder(); 9 | GetAllErrors(allErrors, ex); 10 | return allErrors.ToString(); 11 | } 12 | private static void GetAllErrors(StringBuilder sb, Exception ex) { 13 | sb.AppendLine(); 14 | sb.Append("Error: " + ex.Message); 15 | if (ex.InnerException != null) { 16 | GetAllErrors(sb, ex.InnerException); 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /SharpData/Exceptions/DataTypeNotAvailableException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData.Exceptions { 4 | 5 | public class DataTypeNotAvailableException : Exception { 6 | public DataTypeNotAvailableException(string message) : base(message) { } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SharpData/Exceptions/DatabaseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData { 4 | public class DatabaseException : Exception { 5 | 6 | public string SQL { get; set; } 7 | 8 | public DatabaseException(string message, Exception innerException, string sql) 9 | : base(message, innerException) { 10 | SQL = sql; 11 | } 12 | 13 | public override string ToString() { 14 | return $"Error running SQL: {SQL}\r\n{base.ToString()}"; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SharpData/Exceptions/NotSupportedByDatabaseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData.Exceptions { 4 | public class NotSupportedByDatabaseException : DatabaseException { 5 | public NotSupportedByDatabaseException(string message, Exception innerException, string sql) : base(message, innerException, sql) { 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /SharpData/Exceptions/NotSupportedByDialect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.Logging; 3 | using SharpData.Log; 4 | 5 | namespace SharpData.Exceptions { 6 | public class NotSupportedByDialectException : Exception { 7 | 8 | private static ILogger Logger { get; } = SharpDataLogging.CreateLogger(); 9 | 10 | public string FunctionName { get; set; } 11 | public string DialectName { get; set; } 12 | 13 | public NotSupportedByDialectException(string message, string functionName, string dialectName) : base(message) { 14 | FunctionName = functionName; 15 | DialectName = dialectName; 16 | Logger.LogError($"Dataclient error: operation {functionName} not supported by {dialectName}"); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /SharpData/Exceptions/ProviderNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData.Exceptions { 4 | public class ProviderNotFoundException : Exception { 5 | public ProviderNotFoundException(string message) : base(message) { } 6 | } 7 | } -------------------------------------------------------------------------------- /SharpData/Exceptions/TableNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SharpData.Exceptions { 7 | public class TableNotFoundException : DatabaseException { 8 | public TableNotFoundException(string message, Exception innerException, string sql) : base(message, innerException, sql) { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SharpData/Exceptions/UniqueConstraintException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData.Exceptions { 4 | public class UniqueConstraintException : DatabaseException { 5 | public UniqueConstraintException(string message, Exception innerException, string sql) 6 | : base(message, innerException, sql) { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /SharpData/FakeDataClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Filters; 3 | using SharpData.Fluent; 4 | using SharpData.Schema; 5 | 6 | namespace SharpData { 7 | public class FakeDataClient : IDataClient { 8 | public void Dispose() {} 9 | 10 | public IDatabase Database { get; private set; } 11 | public Dialect Dialect { get; private set; } 12 | public bool ThrowException { get; set; } 13 | public FluentAdd Add { get; private set; } 14 | public FluentRemove Remove { get; private set; } 15 | public FluentRename Rename { get; private set; } 16 | public IFluentInsert Insert { get; private set; } 17 | public IFluentSelect Select { get; private set; } 18 | public IFluentUpdate Update { get; private set; } 19 | public IFluentDelete Delete { get; private set; } 20 | public IFluentCount Count { get; private set; } 21 | public IFluentModify Modify { get; private set; } 22 | 23 | public void AddTable(string tableName, params FluentColumn[] columns) {} 24 | public void AddColumn(string tableName, Column column) {} 25 | public void AddForeignKey(string fkName, string table, string column, string referencingTable, string referencingColumn, OnDelete onDelete) {} 26 | public void AddNamedPrimaryKey(string tableName, string pkName, params string[] columnNames) {} 27 | public void AddPrimaryKey(string tableName, params string[] columnNames) {} 28 | public void AddUniqueKey(string uniqueKeyName, string tableName, params string[] columnNames) {} 29 | public void AddIndex(string indexName, string tableName, params string[] columnNames) {} 30 | public void AddColumnComment(string tableName, string columnName, string comment) {} 31 | public void AddTableComment(string tableName, string comment) {} 32 | 33 | public void RemoveTable(string tableName) { } 34 | public void RemoveColumn(string tableName, string columnName) { } 35 | public void RemovePrimaryKey(string tableName, string primaryKeyName) { } 36 | public void RemoveForeignKey(string foreigKeyName, string tableName) {} 37 | public void RemoveUniqueKey(string uniqueKeyName, string tableName) {} 38 | public void RemoveIndex(string indexName, string table) {} 39 | public void RemoveTableComment(string tableName) {} 40 | public void RemoveColumnComment(string tableName, string columnName) {} 41 | 42 | public void RenameTable(string tableName, string newTableName) {} 43 | public void RenameColumn(string tableName, string columnName, string newColumnName) {} 44 | public void ModifyColumn(string firstTableName, string columnName, Column columnDefinition) {} 45 | 46 | public void Commit() {} 47 | public void RollBack() {} 48 | public void Close() {} 49 | public ResultSet SelectSql(string[] tables, string[] columns, Filter filter, OrderBy[] orderBys, int skip, int take) { 50 | return new ResultSet(); 51 | } 52 | public int InsertSql(string table, string[] columns, object[] values) { 53 | return 0; 54 | } 55 | public object InsertReturningSql(string table, string columnToReturn, string[] columns, object[] values) { 56 | return 0; 57 | } 58 | public int UpdateSql(string table, string[] columns, object[] values, Filter filter) { 59 | return 0; 60 | } 61 | 62 | public int DeleteSql(string table, Filter filter) { 63 | return 0; 64 | } 65 | 66 | public int CountSql(string table, Filter filter) { 67 | return 0; 68 | } 69 | 70 | public bool TableExists(string table) { 71 | return false; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /SharpData/Filters/CompareOperator.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Query { 2 | public enum CompareOperator { 3 | Equals, 4 | GreaterThan, 5 | LessThan, 6 | GreaterOrEqualThan, 7 | LessOrEqualThan, 8 | NotEquals, 9 | Is 10 | } 11 | } -------------------------------------------------------------------------------- /SharpData/Filters/CompareOperatorToSymbol.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Query; 2 | 3 | namespace SharpData.Filters { 4 | 5 | public class CompareOperatorToSymbol { 6 | 7 | public static string Get(CompareOperator compareOperator) { 8 | switch (compareOperator) { 9 | case CompareOperator.Equals: 10 | return "="; 11 | case CompareOperator.GreaterOrEqualThan: 12 | return ">="; 13 | case CompareOperator.GreaterThan: 14 | return ">"; 15 | case CompareOperator.LessOrEqualThan: 16 | return "<="; 17 | case CompareOperator.LessThan: 18 | return "<"; 19 | case CompareOperator.Is: 20 | return "is"; 21 | default: 22 | return ""; 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /SharpData/Filters/Filter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SharpData.Query; 3 | 4 | namespace SharpData.Filters { 5 | public class Filter { 6 | public object Left { get; set; } 7 | public object Right { get; set; } 8 | 9 | protected Filter() {} 10 | 11 | public object[] GetAllValueParameters() { 12 | List parameters = new List(); 13 | GetAllValueParametersRecursive(this, parameters); 14 | return parameters.ToArray(); 15 | } 16 | 17 | private void GetAllValueParametersRecursive(Filter filter, List parameters) { 18 | GoToSubNode(filter.Left, parameters); 19 | GoToSubNode(filter.Right, parameters); 20 | } 21 | 22 | private void GoToSubNode(object node, List parameters) { 23 | if (node is Filter) { 24 | GetAllValueParametersRecursive(node as Filter, parameters); 25 | } 26 | AddValueParameterToList(node, parameters); 27 | } 28 | 29 | private void AddValueParameterToList(object filter, List parameters) { 30 | FilterParameter filterParameter = filter as FilterParameter; 31 | if (filterParameter == null) { 32 | return; 33 | } 34 | 35 | if (filterParameter.FilterParameterType == FilterParameterType.Value) { 36 | parameters.Add(filterParameter.Value); 37 | return; 38 | } 39 | } 40 | 41 | public static Filter Eq(string columnName, object value) { 42 | return CreateFilterCondition(CompareOperator.Equals, columnName, value); 43 | } 44 | 45 | public static Filter Gt(string columnName, object value) { 46 | return CreateFilterCondition(CompareOperator.GreaterThan, columnName, value); 47 | } 48 | 49 | public static Filter Lt(string columnName, object value) { 50 | return CreateFilterCondition(CompareOperator.LessThan, columnName, value); 51 | } 52 | 53 | public static Filter Ge(string columnName, object value) { 54 | return CreateFilterCondition(CompareOperator.GreaterOrEqualThan, columnName, value); 55 | } 56 | 57 | public static Filter Le(string columnName, object value) { 58 | return CreateFilterCondition(CompareOperator.LessOrEqualThan, columnName, value); 59 | } 60 | 61 | private static Filter CreateFilterCondition(CompareOperator compareOperator, string columnName, object value) { 62 | return new FilterCondition { 63 | CompareOperator = compareOperator, 64 | Left = new FilterParameter {Value = columnName, FilterParameterType = FilterParameterType.Column}, 65 | Right = new FilterParameter {Value = value, FilterParameterType = FilterParameterType.Value} 66 | }; 67 | } 68 | 69 | 70 | public static Filter And(Filter leftFilter, Filter rightFilter) { 71 | return CreateFilterLogic(LogicOperator.And, leftFilter, rightFilter); 72 | } 73 | 74 | public static Filter Or(Filter leftFilter, Filter rightFilter) { 75 | return CreateFilterLogic(LogicOperator.Or, leftFilter, rightFilter); 76 | } 77 | 78 | private static Filter CreateFilterLogic(LogicOperator logicOperator, Filter leftFilter, Filter rightFilter) { 79 | return new FilterLogic { 80 | Left = leftFilter, 81 | Right = rightFilter, 82 | LogicOperator = logicOperator 83 | }; 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /SharpData/Filters/FilterCondition.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Query; 2 | 3 | namespace SharpData.Filters { 4 | public class FilterCondition : Filter { 5 | public CompareOperator CompareOperator { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /SharpData/Filters/FilterLogic.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Query; 2 | 3 | namespace SharpData.Filters { 4 | public class FilterLogic : Filter { 5 | public LogicOperator LogicOperator { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /SharpData/Filters/FilterParameter.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Query; 2 | 3 | namespace SharpData.Filters { 4 | public class FilterParameter { 5 | public object Value { get; set; } 6 | public FilterParameterType FilterParameterType { get; set; } 7 | public bool ValueIsNullOrDBNull { 8 | get { 9 | return Value == null || Value == System.DBNull.Value; 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /SharpData/Filters/FilterParameterType.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Query { 2 | public enum FilterParameterType { 3 | Column, 4 | Value 5 | } 6 | } -------------------------------------------------------------------------------- /SharpData/Filters/LogicOperator.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Query { 2 | public enum LogicOperator { 3 | And, 4 | Or 5 | } 6 | } -------------------------------------------------------------------------------- /SharpData/Filters/LogicOperatorToSymbol.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Query; 3 | 4 | namespace SharpData.Filters { 5 | public static class LogicOperatorToSymbol { 6 | 7 | public static string Get(LogicOperator logicOperator) { 8 | return logicOperator.ToString(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SharpData/Fluent/AddColumn.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Schema; 2 | 3 | namespace SharpData.Fluent { 4 | public class AddColumn : DataClientAction, IAddColumnToTable { 5 | private Column _column; 6 | 7 | public AddColumn(IDataClient dataClient, Column column) : base(dataClient) { 8 | _column = column; 9 | } 10 | 11 | public void ToTable(string tableName) { 12 | SetTableNames(tableName); 13 | Execute(); 14 | } 15 | 16 | protected override void ExecuteInternal() { 17 | DataClient.AddColumn(TableNames[0], _column); 18 | } 19 | 20 | public override DataClientAction ReverseAction() { 21 | return new RemoveColumn(DataClient) { 22 | FirstTableName = FirstTableName, 23 | ItemName = _column.ColumnName 24 | }; 25 | } 26 | } 27 | 28 | public interface IAddColumnToTable { 29 | void ToTable(string tableName); 30 | } 31 | } -------------------------------------------------------------------------------- /SharpData/Fluent/AddComment.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public class AddComment : DataClientAction, IAddCommentColumnOrTable, IAddCommentToColumn { 3 | public string Comment { get; set; } 4 | public string ColumnName { get; set; } 5 | 6 | public AddComment(IDataClient dataClient, string comment) : base(dataClient) { 7 | Comment = comment; 8 | } 9 | 10 | public IAddCommentToColumn ToColumn(string columnName) { 11 | ColumnName = columnName; 12 | return this; 13 | } 14 | 15 | public void ToTable(string tableName) { 16 | SetTableNames(tableName); 17 | Execute(); 18 | } 19 | 20 | public void OfTable(string tableName) { 21 | SetTableNames(tableName); 22 | Execute(); 23 | } 24 | 25 | protected override void ExecuteInternal() { 26 | if (ColumnName == null) { 27 | DataClient.AddTableComment(TableNames[0], Comment); 28 | return; 29 | } 30 | DataClient.AddColumnComment(TableNames[0], ColumnName, Comment); 31 | } 32 | 33 | public override DataClientAction ReverseAction() { 34 | return new RemoveComment(DataClient) { 35 | FirstTableName = FirstTableName, 36 | ColumnName = ColumnName 37 | }; 38 | } 39 | } 40 | 41 | public interface IAddCommentColumnOrTable { 42 | void ToTable(string tableName); 43 | IAddCommentToColumn ToColumn(string columnName); 44 | } 45 | 46 | public interface IAddCommentToColumn { 47 | void OfTable(string tableName); 48 | } 49 | } -------------------------------------------------------------------------------- /SharpData/Fluent/AddForeignKey.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | using SharpData.Schema; 3 | 4 | namespace SharpData.Fluent { 5 | 6 | public class AddForeignKey : DataClientAction, IAddForeignKeyOnColumn, IAddForeignKeyOfTable, IAddForeignKeyReferencingColumn, IAddForeignKeyOnDelete { 7 | 8 | public string ForeignKeyName { get; set; } 9 | public string Column { get; set; } 10 | public string ReferencingColumnName { get; set; } 11 | public string ReferencingTable { get; set; } 12 | public OnDelete OnDelete { get; set; } 13 | 14 | public AddForeignKey(IDataClient dataClient, string fkName) : base(dataClient) { 15 | ForeignKeyName = fkName; 16 | } 17 | 18 | public IAddForeignKeyOfTable OnColumn(string columnName) { 19 | Column = columnName; 20 | return this; 21 | } 22 | 23 | public IAddForeignKeyReferencingColumn OfTable(string tableName) { 24 | FirstTableName = tableName; 25 | return this; 26 | } 27 | 28 | public AddForeignKeyStepOfTable ReferencingColumn(string columnName) { 29 | ReferencingColumnName = columnName; 30 | return new AddForeignKeyStepOfTable(this); 31 | } 32 | 33 | public void OnDeleteSetNull() { 34 | OnDelete = OnDelete.SetNull; 35 | Execute(); 36 | } 37 | 38 | public void OnDeleteNoAction() { 39 | OnDelete = OnDelete.NoAction; 40 | Execute(); 41 | } 42 | 43 | public void OnDeleteCascade() { 44 | OnDelete = OnDelete.Cascade; 45 | Execute(); 46 | } 47 | 48 | protected override void ExecuteInternal() { 49 | DataClient.AddForeignKey(ForeignKeyName, TableNames[0], Column, ReferencingTable, ReferencingColumnName, OnDelete); 50 | } 51 | 52 | public override DataClientAction ReverseAction() { 53 | return new RemoveForeignKey(DataClient, ForeignKeyName) { 54 | FirstTableName = FirstTableName 55 | }; 56 | } 57 | } 58 | 59 | public interface IAddForeignKeyOnColumn { 60 | IAddForeignKeyOfTable OnColumn(string columnName); 61 | } 62 | 63 | public interface IAddForeignKeyOfTable { 64 | IAddForeignKeyReferencingColumn OfTable(string tableName); 65 | } 66 | 67 | public interface IAddForeignKeyReferencingColumn { 68 | AddForeignKeyStepOfTable ReferencingColumn(string columnName); 69 | } 70 | 71 | public interface IAddForeignKeyOnDelete { 72 | void OnDeleteSetNull(); 73 | void OnDeleteNoAction(); 74 | void OnDeleteCascade(); 75 | } 76 | 77 | public class AddForeignKeyStepOfTable { 78 | private AddForeignKey _addForeign; 79 | public AddForeignKeyStepOfTable(AddForeignKey addForeign) { 80 | _addForeign = addForeign; 81 | } 82 | 83 | public IAddForeignKeyOnDelete OfTable(string referencingTable) { 84 | _addForeign.ReferencingTable = referencingTable; 85 | return _addForeign; 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /SharpData/Fluent/AddIndexKey.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | 3 | public class AddIndexKey : DataClientAction { 4 | 5 | public string IndexKeyName { get; set; } 6 | public string[] ColumnNames { get; set; } 7 | 8 | public AddIndexKey(IDataClient dataClient) : base(dataClient) { } 9 | 10 | protected override void ExecuteInternal() { 11 | DataClient.AddIndex(IndexKeyName, TableNames[0], ColumnNames); 12 | } 13 | 14 | public override DataClientAction ReverseAction() { 15 | return new RemoveIndexKey(DataClient, IndexKeyName) { 16 | FirstTableName = FirstTableName 17 | }; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /SharpData/Fluent/AddPrimaryKey.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | 3 | namespace SharpData.Fluent { 4 | public class AddPrimaryKey : DataClientAction, IAddPrimaryKeyOnColumns, IAddPrimaryKeyOfTable { 5 | 6 | public string PrimaryKeyName { get; set; } 7 | public string[] ColumnNames { get; set; } 8 | 9 | public AddPrimaryKey(IDataClient dataClient, string primaryKeyName) : base(dataClient) { 10 | PrimaryKeyName = primaryKeyName; 11 | } 12 | 13 | public IAddPrimaryKeyOfTable OnColumns(params string[] columnNames) { 14 | ColumnNames = columnNames; 15 | return this; 16 | } 17 | 18 | public void OfTable(string tableName) { 19 | SetTableNames(tableName); 20 | Execute(); 21 | } 22 | 23 | protected override void ExecuteInternal() { 24 | DataClient.AddNamedPrimaryKey(TableNames[0], PrimaryKeyName, ColumnNames); 25 | } 26 | 27 | public override DataClientAction ReverseAction() { 28 | return new RemovePrimaryKey(DataClient, PrimaryKeyName) { 29 | FirstTableName = FirstTableName 30 | }; 31 | } 32 | } 33 | 34 | public interface IAddPrimaryKeyOnColumns { 35 | IAddPrimaryKeyOfTable OnColumns(params string[] columnNames); 36 | } 37 | 38 | public interface IAddPrimaryKeyOfTable { 39 | void OfTable(string tableName); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SharpData/Fluent/AddTable.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Schema; 2 | 3 | namespace SharpData.Fluent { 4 | 5 | public class AddTable : DataClientAction, IAddTableWithColumns { 6 | 7 | private FluentColumn[] _columns; 8 | 9 | public AddTable(IDataClient dataClient, string tableName) : base(dataClient) { 10 | SetTableNames(tableName); 11 | } 12 | 13 | public void WithColumns(params FluentColumn[] columns) { 14 | _columns = columns; 15 | Execute(); 16 | } 17 | 18 | protected override void ExecuteInternal() { 19 | DataClient.AddTable(TableNames[0], _columns); 20 | } 21 | 22 | public override DataClientAction ReverseAction() { 23 | return new RemoveTable(DataClient) { 24 | FirstTableName = FirstTableName 25 | }; 26 | } 27 | } 28 | 29 | public interface IAddTableWithColumns { 30 | void WithColumns(params FluentColumn[] columns); 31 | } 32 | } -------------------------------------------------------------------------------- /SharpData/Fluent/AddUniqueKey.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | 3 | public class AddUniqueKey : DataClientAction, IAddUniqueKeyOnColumns, IAddUniqueKeyOfTable { 4 | 5 | public string UniqueKeyName { get; set; } 6 | public string[] ColumnNames { get; set; } 7 | 8 | public AddUniqueKey(IDataClient dataClient, string uniqueKeyName) : base(dataClient) { 9 | UniqueKeyName = uniqueKeyName; 10 | } 11 | 12 | public IAddUniqueKeyOfTable OnColumns(params string[] columnNames) { 13 | ColumnNames = columnNames; 14 | return this; 15 | } 16 | 17 | public void OfTable(string tableName) { 18 | FirstTableName = tableName; 19 | Execute(); 20 | } 21 | 22 | protected override void ExecuteInternal() { 23 | DataClient.AddUniqueKey(UniqueKeyName, TableNames[0], ColumnNames); 24 | } 25 | 26 | public override DataClientAction ReverseAction() { 27 | return new RemoveUniqueKey(DataClient, UniqueKeyName) { 28 | FirstTableName = FirstTableName 29 | }; 30 | } 31 | } 32 | 33 | public interface IAddUniqueKeyOnColumns { 34 | IAddUniqueKeyOfTable OnColumns(params string[] columnNames); 35 | } 36 | 37 | public interface IAddUniqueKeyOfTable { 38 | void OfTable(string tableName); 39 | } 40 | } -------------------------------------------------------------------------------- /SharpData/Fluent/Count.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Filters; 2 | 3 | namespace SharpData.Fluent { 4 | public class Count : DataClientAction { 5 | 6 | public Filter Filter { get; set; } 7 | 8 | public int CountedRows { get; set; } 9 | 10 | public Count(IDataClient dataClient) : base(dataClient) { } 11 | 12 | protected override void ExecuteInternal() { 13 | CountedRows = DataClient.CountSql(TableNames[0], Filter); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /SharpData/Fluent/DataClientAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData.Fluent { 4 | public abstract class DataClientAction { 5 | 6 | public string[] TableNames { get; protected set; } 7 | public IDataClient DataClient { get; set; } 8 | 9 | protected DataClientAction(IDataClient dataClient) { 10 | DataClient = dataClient; 11 | } 12 | 13 | public void SetTableNames(params string[] tableNames) { 14 | if(tableNames == null || tableNames.Length == 0) { 15 | throw new ArgumentException("You have to set a table name"); 16 | } 17 | TableNames = tableNames; 18 | } 19 | 20 | public string FirstTableName { 21 | get { return TableNames[0]; } 22 | set {SetTableNames(value);} 23 | } 24 | 25 | public void Execute() { 26 | ExecuteInternal(); 27 | } 28 | 29 | protected abstract void ExecuteInternal(); 30 | public virtual DataClientAction ReverseAction() { 31 | throw new NotSupportedException("Can't reverse " + GetType()); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /SharpData/Fluent/DataClientAddIndexKey.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public class DataClientAddIndexKey { 3 | private AddIndexKey _action; 4 | 5 | public DataClientAddIndexKey(AddIndexKey action) { 6 | _action = action; 7 | } 8 | 9 | public DataClientAddIndexKeyStep2 OnColumns(params string[] columnNames) { 10 | _action.ColumnNames = columnNames; 11 | return new DataClientAddIndexKeyStep2(_action); 12 | } 13 | } 14 | 15 | public class DataClientAddIndexKeyStep2 { 16 | private AddIndexKey _action; 17 | 18 | public DataClientAddIndexKeyStep2(AddIndexKey action) { 19 | _action = action; 20 | } 21 | 22 | public void OfTable(string tableName) { 23 | _action.SetTableNames(tableName); 24 | _action.Execute(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /SharpData/Fluent/Delete.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Filters; 2 | 3 | namespace SharpData.Fluent { 4 | public class Delete : DataClientAction { 5 | 6 | public int AfectedRows { get; set; } 7 | 8 | public Filter Filter { get; set; } 9 | 10 | public Delete(IDataClient dataClient) : base(dataClient) { } 11 | 12 | protected override void ExecuteInternal() { 13 | AfectedRows = DataClient.DeleteSql(TableNames[0], Filter); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /SharpData/Fluent/FluentAdd.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Schema; 2 | 3 | namespace SharpData.Fluent { 4 | public class FluentAdd : ReversibleFluentActions, IFluentAdd { 5 | 6 | private IDataClient _dataClient; 7 | 8 | public FluentAdd(IDataClient dataClient) { 9 | _dataClient = dataClient; 10 | } 11 | 12 | public IAddColumnToTable Column(FluentColumn column) { 13 | var action = new AddColumn(_dataClient, column.Object); 14 | FireOnAction(action); 15 | return action; 16 | } 17 | 18 | public IAddPrimaryKeyOnColumns PrimaryKey(string primaryKeyName) { 19 | var action = new AddPrimaryKey(_dataClient, primaryKeyName); 20 | FireOnAction(action); 21 | return action; 22 | } 23 | 24 | public IAddForeignKeyOnColumn ForeignKey(string foreignKeyName) { 25 | var action = new AddForeignKey(_dataClient, foreignKeyName); 26 | FireOnAction(action); 27 | return action; 28 | } 29 | 30 | public IAddUniqueKeyOnColumns UniqueKey(string uniqueKeyName) { 31 | var action = new AddUniqueKey(_dataClient, uniqueKeyName); 32 | FireOnAction(action); 33 | return action; 34 | } 35 | 36 | public DataClientAddIndexKey IndexKey(string indexKeyName) { 37 | var action = new AddIndexKey(_dataClient) { IndexKeyName = indexKeyName }; 38 | FireOnAction(action); 39 | return new DataClientAddIndexKey(action); 40 | } 41 | 42 | public IAddTableWithColumns Table(string tableName) { 43 | var action = new AddTable(_dataClient, tableName); 44 | FireOnAction(action); 45 | return action; 46 | } 47 | 48 | public IAddCommentColumnOrTable Comment(string comment) { 49 | var action = new AddComment(_dataClient, comment); 50 | FireOnAction(action); 51 | return action; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /SharpData/Fluent/FluentCount.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Filters; 3 | 4 | namespace SharpData.Fluent { 5 | public class FluentCount : IFluentCount, IFluentCountFilter { 6 | 7 | private Count _count; 8 | 9 | public FluentCount(IDataClient client) { 10 | _count = new Count(client); 11 | } 12 | 13 | public IFluentCountFilter Table(string tableName) { 14 | _count.SetTableNames(tableName); 15 | return this; 16 | } 17 | 18 | public int AllRows() { 19 | _count.Execute(); 20 | return _count.CountedRows; 21 | } 22 | 23 | public int Where(Filter where) { 24 | _count.Filter = where; 25 | _count.Execute(); 26 | return _count.CountedRows; 27 | } 28 | } 29 | 30 | public interface IFluentCount { 31 | IFluentCountFilter Table(string tableName); 32 | } 33 | 34 | public interface IFluentCountFilter { 35 | int AllRows(); 36 | int Where(Filter where); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SharpData/Fluent/FluentDelete.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Filters; 2 | 3 | namespace SharpData.Fluent { 4 | public class FluentDelete : IFluentDelete, IFluentDeleteFilter { 5 | 6 | private Delete _delete; 7 | 8 | public FluentDelete(IDataClient client) { 9 | _delete = new Delete(client); 10 | } 11 | 12 | public IFluentDeleteFilter From(string tableName) { 13 | _delete.SetTableNames(tableName); 14 | return this; 15 | } 16 | 17 | public int AllRows() { 18 | _delete.Execute(); 19 | return _delete.AfectedRows; 20 | } 21 | 22 | public int Where(Filter where) { 23 | _delete.Filter = where; 24 | _delete.Execute(); 25 | return _delete.AfectedRows; 26 | } 27 | } 28 | 29 | public interface IFluentDelete { 30 | IFluentDeleteFilter From(string tableName); 31 | } 32 | 33 | public interface IFluentDeleteFilter { 34 | int AllRows(); 35 | int Where(Filter where); 36 | } 37 | } -------------------------------------------------------------------------------- /SharpData/Fluent/FluentInsert.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Util; 2 | using System; 3 | 4 | namespace SharpData.Fluent { 5 | 6 | public class FluentInsert : IFluentInsert, 7 | IFluentInsertColumns, 8 | IFluentInsertValues, 9 | IFluentInsertObject, 10 | IFluentInsertReturning { 11 | 12 | private readonly Insert _insert; 13 | 14 | public FluentInsert(IDataClient client) { 15 | _insert = new Insert(client); 16 | } 17 | 18 | public IFluentInsertColumns Into(string tableName) { 19 | _insert.SetTableNames(tableName); 20 | return this; 21 | } 22 | 23 | public IFluentInsertValues Columns(params string[] columns) { 24 | _insert.Columns = columns; 25 | return this; 26 | } 27 | 28 | public IFluentInsertValues Values(params object[] values) { 29 | _insert.Values = values; 30 | _insert.Execute(); 31 | return this; 32 | } 33 | 34 | public IFluentInsertReturning ValuesAnd(params object[] values) { 35 | _insert.Values = values; 36 | return this; 37 | } 38 | 39 | public IFluentInsertObject Object(object obj) { 40 | _insert.Columns = ReflectionHelper.GetPropertiesNames(obj.GetType()); 41 | _insert.Values = ReflectionHelper.GetPropertiesValues(obj); 42 | _insert.Execute(); 43 | return this; 44 | } 45 | 46 | public IFluentInsertReturning ObjectAnd(object obj) { 47 | _insert.Columns = ReflectionHelper.GetPropertiesNames(obj.GetType()); 48 | _insert.Values = ReflectionHelper.GetPropertiesValues(obj); 49 | return this; 50 | } 51 | 52 | public T Return(string columnName) { 53 | _insert.ColumnToReturn = columnName; 54 | _insert.ColumnToReturnType = typeof(T); 55 | _insert.Execute(); 56 | return (T)Convert.ChangeType(_insert.ColumnToReturnValue, typeof(T)); 57 | } 58 | } 59 | 60 | public interface IFluentInsert { 61 | IFluentInsertColumns Into(string tableName); 62 | } 63 | 64 | public interface IFluentInsertColumns { 65 | IFluentInsertObject Object(object obj); 66 | IFluentInsertReturning ObjectAnd(object obj); 67 | IFluentInsertValues Columns(params string[] columns); 68 | } 69 | 70 | public interface IFluentInsertObject { 71 | IFluentInsertObject Object(object obj); 72 | } 73 | 74 | public interface IFluentInsertValues { 75 | IFluentInsertValues Values(params object[] values); 76 | IFluentInsertReturning ValuesAnd(params object[] values); 77 | } 78 | 79 | public interface IFluentInsertReturning { 80 | T Return(string columnName); 81 | } 82 | } -------------------------------------------------------------------------------- /SharpData/Fluent/FluentRemove.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | 3 | public class FluentRemove { 4 | 5 | private IDataClient _dataClient; 6 | 7 | public FluentRemove(IDataClient dataClient) { 8 | _dataClient = dataClient; 9 | } 10 | 11 | public IRemoveFromTable Column(string columnName) { 12 | return new RemoveColumn(_dataClient) { ItemName = columnName }; 13 | } 14 | 15 | public IRemoveCommentFromColumnOrTable Comment { 16 | get { return new RemoveComment(_dataClient); } 17 | } 18 | 19 | public IRemoveFromTable PrimaryKey(string primaryKeyName) { 20 | return new RemovePrimaryKey(_dataClient, primaryKeyName); 21 | } 22 | 23 | public IRemoveFromTable ForeignKey(string foreignKeyName) { 24 | return new RemoveForeignKey(_dataClient, foreignKeyName); 25 | } 26 | 27 | public IRemoveFromTable UniqueKey(string uniqueKeyName) { 28 | return new RemoveUniqueKey(_dataClient, uniqueKeyName) { ItemName = uniqueKeyName }; 29 | } 30 | 31 | public IRemoveFromTable IndexKey(string indexKeyName) { 32 | return new RemoveIndexKey(_dataClient, indexKeyName) { ItemName = indexKeyName }; 33 | } 34 | 35 | public void Table(string tableName) { 36 | var action = new RemoveTable(_dataClient); 37 | action.SetTableNames(tableName); 38 | action.Execute(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /SharpData/Fluent/FluentRename.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public class FluentRename : ReversibleFluentActions, IFluentRename { 3 | 4 | private IDataClient _dataClient; 5 | 6 | public FluentRename(IDataClient dataClient) { 7 | _dataClient = dataClient; 8 | } 9 | 10 | public IRenameTableTo Table(string tableName) { 11 | var action = new RenameTable(_dataClient, tableName); 12 | FireOnAction(action); 13 | return action; 14 | } 15 | 16 | public IRenameColumnOfTable Column(string columnName) { 17 | var action = new RenameColumn(_dataClient, columnName); 18 | FireOnAction(action); 19 | return action; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SharpData/Fluent/FluentScalar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SharpData.Fluent { 7 | public class FluentScalar { 8 | 9 | //private IDataClient _client; 10 | //private string _table; 11 | //private FluentWhere _fluentWhere; 12 | 13 | //public FluentScalar(IDataClient client, string table, FluentWhere fluentWhere) 14 | // : this(client, table) { 15 | // _fluentWhere = fluentWhere; 16 | //} 17 | 18 | //public FluentScalar(IDataClient client, string table) { 19 | // _client = client; 20 | // _table = table; 21 | //} 22 | 23 | //public T Column(string column) { 24 | // string sql = _client.Dialect.GetSelectSql(_table, new string[] { column } ); 25 | 26 | // if (_fluentWhere == null) { 27 | // return (T)_client.Database.QueryScalar(sql); 28 | // } 29 | 30 | // String sqlWhere = _fluentWhere.GetSql(0); 31 | // In[] parametersWhere = _fluentWhere.GetParameters(0); 32 | 33 | // object x = _client.Database.QueryScalar(String.Format("{0} {1}", sql, sqlWhere), parametersWhere); 34 | 35 | // return (T) Convert.ChangeType(x, typeof(T)); 36 | //} 37 | } 38 | } -------------------------------------------------------------------------------- /SharpData/Fluent/FluentSelect.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Filters; 2 | using SharpData.Schema; 3 | 4 | namespace SharpData.Fluent { 5 | public class FluentSelect : IFluentSelect, IFluentSelectTable, IFluentSelectFilter, IFluentSelectOrderBy, IFluentSelectToResultSet { 6 | private Select _select; 7 | 8 | public FluentSelect(IDataClient client) { 9 | _select = new Select(client); 10 | } 11 | 12 | public IFluentSelectTable Columns(params string[] columns) { 13 | _select.Columns = columns; 14 | return this; 15 | } 16 | 17 | public IFluentSelectTable AllColumns() { 18 | return Columns("*"); 19 | } 20 | 21 | public IFluentSelectFilter From(params string[] tableName) { 22 | _select.SetTableNames(tableName); 23 | return this; 24 | } 25 | 26 | public IFluentSelectOrderBy Where(Filter where) { 27 | _select.Filter = where; 28 | return this; 29 | } 30 | 31 | public IFluentSelectToResultSet OrderBy(params OrderBy[] orderBy) { 32 | _select.OrderBy = orderBy; 33 | return this; 34 | } 35 | 36 | public ResultSet AllRows() { 37 | _select.Execute(); 38 | return _select.ResultSet; 39 | } 40 | 41 | public ResultSet SkipTake(int skip, int take) { 42 | _select.Skip = skip; 43 | _select.Take = take; 44 | _select.Execute(); 45 | return _select.ResultSet; 46 | } 47 | } 48 | 49 | public interface IFluentSelect { 50 | IFluentSelectTable Columns(params string[] columns); 51 | IFluentSelectTable AllColumns(); 52 | } 53 | 54 | public interface IFluentSelectTable { 55 | IFluentSelectFilter From(params string[] tableNames); 56 | } 57 | 58 | public interface IFluentSelectFilter { 59 | IFluentSelectOrderBy Where(Filter where); 60 | IFluentSelectToResultSet OrderBy(params OrderBy[] orderBys); 61 | ResultSet SkipTake(int skip, int take); 62 | ResultSet AllRows(); 63 | } 64 | 65 | public interface IFluentSelectOrderBy { 66 | IFluentSelectToResultSet OrderBy(params OrderBy[] orderBys); 67 | ResultSet SkipTake(int skip, int take); 68 | ResultSet AllRows(); 69 | } 70 | 71 | public interface IFluentSelectToResultSet { 72 | ResultSet AllRows(); 73 | ResultSet SkipTake(int skip, int take); 74 | } 75 | } -------------------------------------------------------------------------------- /SharpData/Fluent/FluentUpdate.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Filters; 2 | 3 | namespace SharpData.Fluent { 4 | 5 | public class FluentUpdate : IFluentUpdate, IFluentUpdateColumns, IFluentUpdateValues, IFluentUpdateFilter { 6 | 7 | private Update _update; 8 | 9 | public FluentUpdate(IDataClient client) { 10 | _update = new Update(client); 11 | } 12 | 13 | public IFluentUpdateColumns Table(string tableName) { 14 | _update.SetTableNames(tableName); 15 | return this; 16 | } 17 | 18 | public IFluentUpdateValues SetColumns(params string[] columnNames) { 19 | _update.Columns = columnNames; 20 | return this; 21 | } 22 | 23 | public IFluentUpdateFilter ToValues(params object[] values) { 24 | _update.Values = values; 25 | return this; 26 | } 27 | 28 | public int AllRows() { 29 | _update.Execute(); 30 | return _update.AfectedRows; 31 | } 32 | 33 | public int Where(Filter where) { 34 | _update.Filter = where; 35 | _update.Execute(); 36 | return _update.AfectedRows; 37 | } 38 | } 39 | 40 | public interface IFluentUpdate { 41 | IFluentUpdateColumns Table(string tableName); 42 | } 43 | 44 | public interface IFluentUpdateColumns { 45 | IFluentUpdateValues SetColumns(params string[] columnNames); 46 | } 47 | 48 | public interface IFluentUpdateValues { 49 | IFluentUpdateFilter ToValues(params object[] values); 50 | } 51 | 52 | public interface IFluentUpdateFilter { 53 | int AllRows(); 54 | int Where(Filter where); 55 | } 56 | } -------------------------------------------------------------------------------- /SharpData/Fluent/IFluentAdd.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Schema; 2 | 3 | namespace SharpData.Fluent { 4 | public interface IFluentAdd { 5 | IAddColumnToTable Column(FluentColumn column); 6 | IAddPrimaryKeyOnColumns PrimaryKey(string primaryKeyName); 7 | IAddForeignKeyOnColumn ForeignKey(string foreignKeyName); 8 | IAddUniqueKeyOnColumns UniqueKey(string uniqueKeyName); 9 | DataClientAddIndexKey IndexKey(string indexKeyName); 10 | IAddTableWithColumns Table(string tableName); 11 | IAddCommentColumnOrTable Comment(string comment); 12 | } 13 | } -------------------------------------------------------------------------------- /SharpData/Fluent/IFluentModify.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public interface IFluentModify { 3 | ModifyColumn Column(string columnName); 4 | } 5 | 6 | public class FluentModify : IFluentModify { 7 | private IDataClient _dataClient; 8 | 9 | public FluentModify(IDataClient dataClient) { 10 | _dataClient = dataClient; 11 | } 12 | 13 | public ModifyColumn Column(string columnName) { 14 | return new ModifyColumn(_dataClient, columnName); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SharpData/Fluent/IFluentRename.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public interface IFluentRename { 3 | IRenameTableTo Table(string tableName); 4 | IRenameColumnOfTable Column(string columnName); 5 | } 6 | } -------------------------------------------------------------------------------- /SharpData/Fluent/IRemoveFromTable.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public interface IRemoveFromTable { 3 | void FromTable(string tableName); 4 | } 5 | } -------------------------------------------------------------------------------- /SharpData/Fluent/Insert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace SharpData.Fluent { 3 | public class Insert : DataClientAction { 4 | 5 | public string[] Columns { get; set; } 6 | public object[] Values { get; set; } 7 | public string ColumnToReturn { get; set; } 8 | public Type ColumnToReturnType { get; set; } 9 | public object ColumnToReturnValue { get; set; } 10 | 11 | public Insert(IDataClient dataClient) : base(dataClient) { } 12 | 13 | protected override void ExecuteInternal() { 14 | 15 | if(ColumnToReturn != null) { 16 | ColumnToReturnValue = DataClient.InsertReturningSql(TableNames[0], ColumnToReturn, Columns, Values); 17 | return; 18 | } 19 | DataClient.InsertSql(TableNames[0], Columns, Values); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SharpData/Fluent/ModifyColumn.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Schema; 2 | 3 | namespace SharpData.Fluent { 4 | public class ModifyColumn : DataClientAction { 5 | private string _columnName; 6 | private FluentColumn _columnDefinition; 7 | 8 | public ModifyColumn(IDataClient dataClient, string columnName) 9 | : base(dataClient) { 10 | _columnName = columnName; 11 | } 12 | 13 | public ModifyColumn OfTable(string tableName) { 14 | SetTableNames(tableName); 15 | return this; 16 | } 17 | 18 | public void WithDefinition(FluentColumn columnDef) { 19 | _columnDefinition = columnDef; 20 | Execute(); 21 | } 22 | 23 | protected override void ExecuteInternal() { 24 | DataClient.ModifyColumn(FirstTableName, _columnName, _columnDefinition.Object); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RemoveColumn.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | 3 | namespace SharpData.Fluent { 4 | public class RemoveColumn : RemoveItemFromTable { 5 | 6 | public RemoveColumn(IDataClient dataClient) : base(dataClient) {} 7 | 8 | protected override void ExecuteInternal() { 9 | DataClient.RemoveColumn(TableNames[0], ItemName); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RemoveComment.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public class RemoveComment : DataClientAction, IRemoveCommentFromColumnOrTable, IRemoveCommentFromColumn { 3 | public string ColumnName { get; set; } 4 | 5 | public RemoveComment(IDataClient dataClient) : base(dataClient) { 6 | } 7 | 8 | public void FromTable(string tableName) { 9 | SetTableNames(tableName); 10 | Execute(); 11 | } 12 | 13 | public IRemoveCommentFromColumn FromColumn(string column) { 14 | ColumnName = column; 15 | return this; 16 | } 17 | 18 | public void OfTable(string tableName) { 19 | SetTableNames(tableName); 20 | Execute(); 21 | } 22 | 23 | protected override void ExecuteInternal() { 24 | if (ColumnName == null) { 25 | DataClient.RemoveTableComment(TableNames[0]); 26 | return; 27 | } 28 | DataClient.RemoveColumnComment(TableNames[0], ColumnName); 29 | } 30 | } 31 | 32 | public interface IRemoveCommentFromColumnOrTable { 33 | IRemoveCommentFromColumn FromColumn(string column); 34 | void FromTable(string tableName); 35 | } 36 | 37 | public interface IRemoveCommentFromColumn { 38 | void OfTable(string tableName); 39 | } 40 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RemoveForeignKey.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | 3 | namespace SharpData.Fluent { 4 | public class RemoveForeignKey : RemoveItemFromTable { 5 | 6 | public RemoveForeignKey(IDataClient dataClient, string foreignKeyName) : base(dataClient) { 7 | ItemName = foreignKeyName; 8 | } 9 | 10 | protected override void ExecuteInternal() { 11 | DataClient.RemoveForeignKey(ItemName, TableNames[0]); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RemoveIndexKey.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | 3 | namespace SharpData.Fluent { 4 | public class RemoveIndexKey : RemoveItemFromTable, IRemoveFromTable { 5 | public RemoveIndexKey(IDataClient dataClient, string indexKeyName) : base(dataClient) { 6 | ItemName = indexKeyName; 7 | } 8 | 9 | protected override void ExecuteInternal() { 10 | DataClient.RemoveIndex(ItemName, TableNames[0]); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RemoveItem.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public abstract class RemoveItemFromTable : DataClientAction, IRemoveFromTable { 3 | public string ItemName { get; set; } 4 | protected RemoveItemFromTable(IDataClient dataClient) : base(dataClient) {} 5 | 6 | public void FromTable(string tableName) { 7 | SetTableNames(tableName); 8 | Execute(); 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RemovePrimaryKey.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public class RemovePrimaryKey : RemoveItemFromTable { 3 | public RemovePrimaryKey(IDataClient dataClient, string primaryKeyName) : base(dataClient) { 4 | ItemName = primaryKeyName; 5 | } 6 | 7 | protected override void ExecuteInternal() { 8 | DataClient.RemovePrimaryKey(FirstTableName, ItemName); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SharpData/Fluent/RemoveTable.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | 3 | namespace SharpData.Fluent { 4 | public class RemoveTable : DataClientAction { 5 | public RemoveTable(IDataClient dataClient) : base(dataClient) {} 6 | 7 | protected override void ExecuteInternal() { 8 | DataClient.RemoveTable(TableNames[0]); 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RemoveUniqueKey.cs: -------------------------------------------------------------------------------- 1 | using SharpData; 2 | 3 | namespace SharpData.Fluent { 4 | public class RemoveUniqueKey : RemoveItemFromTable { 5 | public RemoveUniqueKey(IDataClient dataClient, string uniqueKeyName) : base(dataClient) { 6 | ItemName = uniqueKeyName; 7 | } 8 | 9 | public void FromTable(string tableName) { 10 | SetTableNames(tableName); 11 | Execute(); 12 | } 13 | 14 | protected override void ExecuteInternal() { 15 | DataClient.RemoveUniqueKey(ItemName, TableNames[0]); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RenameColumn.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public class RenameColumn : DataClientAction, IRenameColumnOfTable, IRenameColumnTo { 3 | private string _newName, _columnName; 4 | 5 | public RenameColumn(IDataClient dataClient, string columnName) 6 | : base(dataClient) { 7 | _columnName = columnName; 8 | } 9 | 10 | public IRenameColumnTo OfTable(string tableName) { 11 | SetTableNames(tableName); 12 | return this; 13 | } 14 | 15 | public void To(string newName) { 16 | _newName = newName; 17 | Execute(); 18 | } 19 | 20 | protected override void ExecuteInternal() { 21 | DataClient.RenameColumn(TableNames[0], _columnName, _newName); 22 | } 23 | 24 | public override DataClientAction ReverseAction() { 25 | return new RenameColumn(DataClient, _newName) { 26 | _newName = _columnName, 27 | FirstTableName = FirstTableName 28 | }; 29 | } 30 | } 31 | 32 | public interface IRenameColumnOfTable { 33 | IRenameColumnTo OfTable(string tableName); 34 | } 35 | 36 | public interface IRenameColumnTo { 37 | void To(string newName); 38 | } 39 | } -------------------------------------------------------------------------------- /SharpData/Fluent/RenameTable.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Fluent { 2 | public class RenameTable : DataClientAction, IRenameTableTo { 3 | private string _newName; 4 | 5 | public RenameTable(IDataClient dataClient, string tableName) : base(dataClient) { 6 | SetTableNames(tableName); 7 | } 8 | 9 | public void To(string newName) { 10 | _newName = newName; 11 | Execute(); 12 | } 13 | 14 | protected override void ExecuteInternal() { 15 | DataClient.RenameTable(TableNames[0], _newName); 16 | } 17 | 18 | public override DataClientAction ReverseAction() { 19 | return new RenameTable(DataClient, _newName) { 20 | _newName = FirstTableName 21 | }; 22 | } 23 | } 24 | 25 | public interface IRenameTableTo { 26 | void To(string newName); 27 | } 28 | } -------------------------------------------------------------------------------- /SharpData/Fluent/ReversableFluentActions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData.Fluent { 4 | public class ReversibleFluentActions { 5 | public event Action OnAction; 6 | 7 | public void FireOnAction(DataClientAction action) { 8 | if (OnAction != null) { 9 | OnAction(action); 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /SharpData/Fluent/Select.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Filters; 3 | using SharpData.Schema; 4 | 5 | namespace SharpData.Fluent { 6 | public class Select : DataClientAction { 7 | 8 | public string[] Columns { get; set; } 9 | public Filter Filter { get; set; } 10 | public OrderBy[] OrderBy { get; set; } 11 | public ResultSet ResultSet { get; set; } 12 | 13 | public int Skip { get; set; } 14 | public int Take { get; set; } 15 | 16 | public Select(IDataClient dataClient) : base(dataClient) { } 17 | 18 | protected override void ExecuteInternal() { 19 | ResultSet = DataClient.SelectSql(TableNames, Columns, Filter, OrderBy, Skip, Take); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /SharpData/Fluent/Update.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Filters; 2 | 3 | namespace SharpData.Fluent { 4 | public class Update : DataClientAction { 5 | 6 | public Filter Filter { get; set; } 7 | public string[] Columns { get; set; } 8 | public object[] Values { get; set; } 9 | public int AfectedRows { get; set; } 10 | 11 | public Update(IDataClient dataClient) : base(dataClient) { } 12 | 13 | protected override void ExecuteInternal() { 14 | AfectedRows = DataClient.UpdateSql(TableNames[0], Columns, Values, Filter); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SharpData/GenericDbTypeMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace SharpData { 8 | public static class GenericDbTypeMap { 9 | 10 | private static Dictionary _typeMap; 11 | 12 | static GenericDbTypeMap() { 13 | _typeMap = new Dictionary(); 14 | _typeMap[typeof(byte)] = DbType.Byte; 15 | _typeMap[typeof(sbyte)] = DbType.SByte; 16 | _typeMap[typeof(short)] = DbType.Int16; 17 | _typeMap[typeof(ushort)] = DbType.UInt16; 18 | _typeMap[typeof(int)] = DbType.Int32; 19 | _typeMap[typeof(uint)] = DbType.UInt32; 20 | _typeMap[typeof(long)] = DbType.Int64; 21 | _typeMap[typeof(ulong)] = DbType.UInt64; 22 | _typeMap[typeof(float)] = DbType.Single; 23 | _typeMap[typeof(double)] = DbType.Double; 24 | _typeMap[typeof(decimal)] = DbType.Decimal; 25 | _typeMap[typeof(bool)] = DbType.Boolean; 26 | _typeMap[typeof(string)] = DbType.String; 27 | _typeMap[typeof(char)] = DbType.StringFixedLength; 28 | _typeMap[typeof(Guid)] = DbType.Guid; 29 | _typeMap[typeof(DateTime)] = DbType.DateTime; 30 | _typeMap[typeof(DateTimeOffset)] = DbType.DateTimeOffset; 31 | _typeMap[typeof(byte[])] = DbType.Binary; 32 | _typeMap[typeof(byte?)] = DbType.Byte; 33 | _typeMap[typeof(sbyte?)] = DbType.SByte; 34 | _typeMap[typeof(short?)] = DbType.Int16; 35 | _typeMap[typeof(ushort?)] = DbType.UInt16; 36 | _typeMap[typeof(int?)] = DbType.Int32; 37 | _typeMap[typeof(uint?)] = DbType.UInt32; 38 | _typeMap[typeof(long?)] = DbType.Int64; 39 | _typeMap[typeof(ulong?)] = DbType.UInt64; 40 | _typeMap[typeof(float?)] = DbType.Single; 41 | _typeMap[typeof(double?)] = DbType.Double; 42 | _typeMap[typeof(decimal?)] = DbType.Decimal; 43 | _typeMap[typeof(bool?)] = DbType.Boolean; 44 | _typeMap[typeof(char?)] = DbType.StringFixedLength; 45 | _typeMap[typeof(Guid?)] = DbType.Guid; 46 | _typeMap[typeof(DateTime?)] = DbType.DateTime; 47 | _typeMap[typeof(DateTimeOffset?)] = DbType.DateTimeOffset; 48 | _typeMap[typeof(DBNull)] = DbType.String; 49 | } 50 | 51 | public static DbType GetDbType(Type type) { 52 | return _typeMap[type]; 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SharpData/IDataClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SharpData.Filters; 3 | using SharpData.Fluent; 4 | using SharpData.Schema; 5 | 6 | namespace SharpData { 7 | 8 | public interface IDataClient : IDisposable { 9 | 10 | IDatabase Database { get; } 11 | Dialect Dialect { get; } 12 | 13 | bool ThrowException { get; set; } 14 | 15 | FluentAdd Add { get; } 16 | FluentRemove Remove { get; } 17 | FluentRename Rename { get; } 18 | 19 | IFluentInsert Insert { get; } 20 | IFluentSelect Select { get; } 21 | IFluentUpdate Update { get; } 22 | IFluentDelete Delete { get; } 23 | IFluentCount Count { get; } 24 | IFluentModify Modify { get; } 25 | 26 | void AddTable(string tableName, params FluentColumn[] columns); 27 | void AddColumn(string tableName, Column column); 28 | void AddForeignKey(string fkName, string table, string column, string referencingTable, string referencingColumn, OnDelete onDelete); 29 | void AddNamedPrimaryKey(string tableName, string pkName, params string[] columnNames); 30 | void AddPrimaryKey(string tableName, params string[] columnNames); 31 | void AddUniqueKey(string uniqueKeyName, string tableName, params string[] columnNames); 32 | void AddIndex(string indexName, string tableName, params string[] columnNames); 33 | void AddColumnComment(string tableName, string columnName, string comment); 34 | void AddTableComment(string tableName, string comment); 35 | 36 | void RemoveColumn(string tableName, string columnName); 37 | void RemovePrimaryKey(string tableName, string primaryKeyName); 38 | void RemoveForeignKey(string foreigKeyName, string tableName); 39 | void RemoveTable(string tableName); 40 | void RemoveUniqueKey(string uniqueKeyName, string tableName); 41 | void RemoveIndex(string indexName, string table); 42 | void RemoveTableComment(string tableName); 43 | void RemoveColumnComment(string tableName, string columnName); 44 | 45 | void RenameTable(string tableName, string newTableName); 46 | void RenameColumn(string tableName, string columnName, string newColumnName); 47 | 48 | void ModifyColumn(string firstTableName, string columnName, Column columnDefinition); 49 | 50 | void Commit(); 51 | void RollBack(); 52 | void Close(); 53 | 54 | ResultSet SelectSql(string[] tables, string[] columns, Filter filter, OrderBy[] orderBys, int skip, int take); 55 | 56 | int InsertSql(string table, string[] columns, object[] values); 57 | object InsertReturningSql(string table, string columnToReturn, string[] columns, object[] values); 58 | int UpdateSql(string table, string[] columns, object[] values, Filter filter); 59 | int DeleteSql(string table, Filter filter); 60 | int CountSql(string table, Filter filter); 61 | 62 | bool TableExists(string table); 63 | 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SharpData/IDataClientEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SharpData { 5 | public static class IDataClientEx { 6 | public static int ExecSqlFormattable(this IDataClient client, FormattableString formattable) { 7 | var (Sql, Pars) = Prepare(client, formattable); 8 | return client.Database.ExecuteSql(Sql, Pars); 9 | } 10 | 11 | public static int ExecSqlFormattableCommitAndDispose(this IDataClient client, FormattableString formattable) { 12 | var (Sql, Pars) = Prepare(client, formattable); 13 | return client.Database.ExecuteSqlCommitAndDispose(Sql, Pars); 14 | } 15 | 16 | public static ResultSet QueryFormattable(this IDataClient client, FormattableString formattable) { 17 | var (Sql, Pars) = Prepare(client, formattable); 18 | return client.Database.Query(Sql, Pars); 19 | } 20 | 21 | public static ResultSet QueryFormattableAndDispose(this IDataClient client, FormattableString formattable) { 22 | var (Sql, Pars) = Prepare(client, formattable); 23 | return client.Database.QueryAndDispose(Sql, Pars); 24 | } 25 | 26 | public static List QueryFormattable(this IDataClient client, FormattableString formattable) where T : new() { 27 | var (Sql, Pars) = Prepare(client, formattable); 28 | return client.Database.Query(Sql, Pars).Map(); 29 | } 30 | 31 | public static List QueryFormattableAndDispose(this IDataClient client, FormattableString formattable) where T : new() { 32 | var (Sql, Pars) = Prepare(client, formattable); 33 | return client.Database.QueryAndDispose(Sql, Pars).Map(); 34 | } 35 | 36 | private static (string Sql, In[] Pars) Prepare(IDataClient client, FormattableString formattable) { 37 | var sql = formattable.Format; 38 | var prefix = client.Dialect.ParameterPrefix; 39 | var pars = new List(); 40 | for (var i = 0; i < formattable.ArgumentCount; i++) { 41 | var parName = prefix + "par" + i; 42 | sql = sql.Replace("{" + i + "}", parName); 43 | pars.Add(In.Named(parName, formattable.GetArgument(i))); 44 | } 45 | return (sql, pars.ToArray()); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /SharpData/IDataClientObjectEx.cs: -------------------------------------------------------------------------------- 1 | using SharpData.Filters; 2 | using SharpData.Util; 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | 8 | namespace SharpData { 9 | public static class IDataClientObjectEx { 10 | public static T LoadById(this IDataClient client, 11 | string table, 12 | object id, 13 | Expression> idProperty) where T : new() { 14 | var unboxed = ReflectionHelper.StripConvert(idProperty); 15 | var propertyInfo = ((MemberExpression)unboxed.Body).Member as PropertyInfo; 16 | var columns = ReflectionHelper.GetPropertiesNames(typeof(T)); 17 | return client.Select 18 | .Columns(columns) 19 | .From(table) 20 | .Where(Filter.Eq(propertyInfo.Name, id)) 21 | .AllRows() 22 | .Map() 23 | .FirstOrDefault(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /SharpData/IDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using SharpData.Databases; 4 | using System.Data.Common; 5 | 6 | namespace SharpData { 7 | public interface IDataProvider { 8 | DbProviderType Name { get; } 9 | DatabaseKind DatabaseKind { get; } 10 | IDbConnection GetConnection(); 11 | void ConfigCommand(IDbCommand command, object[] parameters, bool isBulk); 12 | DbParameter GetParameter(); 13 | DbParameter GetParameter(In parameter, bool isBulk); 14 | DbParameter GetParameterCursor(); 15 | DatabaseException CreateSpecificException(Exception exception, string sql); 16 | string GetPreCommand(); 17 | string GetOnErrorCommand(); 18 | } 19 | } -------------------------------------------------------------------------------- /SharpData/IDatabase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | 4 | namespace SharpData { 5 | public interface IDatabase : IDisposable { 6 | IDataProvider Provider { get; } 7 | string ConnectionString { get; } 8 | int Timeout { get; set; } 9 | object CallStoredFunction(DbType returnType, string call, params object[] parameters); 10 | ResultSet CallStoredProcedure(string call, params object[] parameters); 11 | int ExecuteSql(string call, params object[] parameters); 12 | int ExecuteBulkSql(string call, params object[] parameters); 13 | int ExecuteSqlCommitAndDispose(string call, params object[] parameters); 14 | int ExecuteBulkSqlCommitAndDispose(string call, params object[] parameters); 15 | void ExecuteStoredProcedure(string call, params object[] parameters); 16 | void ExecuteBulkStoredProcedure(string call, params object[] parameters); 17 | void ExecuteBulkStoredProcedureAndDispose(string call, params object[] parameters); 18 | ResultSet Query(string call, params object[] parameters); 19 | ResultSet QueryAndDispose(string call, params object[] parameters); 20 | object QueryScalar(string call, params object[] parameters); 21 | object QueryScalarAndDispose(string call, params object[] parameters); 22 | void Commit(); 23 | void RollBack(); 24 | void Close(); 25 | } 26 | } -------------------------------------------------------------------------------- /SharpData/ISharpFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace SharpData { 4 | public interface ISharpFactory { 5 | string ConnectionString { get; } 6 | DbProviderFactory DbProviderFactory { get; } 7 | IDataProvider CreateDataProvider(); 8 | IDatabase CreateDatabase(); 9 | IDataClient CreateDataClient(); 10 | Dialect CreateDialect(); 11 | } 12 | } -------------------------------------------------------------------------------- /SharpData/In.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using System.Diagnostics; 3 | 4 | namespace SharpData { 5 | [DebuggerDisplay("[{Name}][{Value}]")] 6 | public class In { 7 | public string Name { get; set; } 8 | public object Value { get; set; } 9 | public DbType? DbType { get; set; } 10 | 11 | public static In Named(string name, object parameter, DbType? dbType = null) { 12 | return new In { Value = parameter, Name = name, DbType = dbType }; 13 | } 14 | 15 | public static In Par(object parameter, DbType? dbType = null) { 16 | return new In { Value = parameter, DbType = dbType }; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SharpData/InOut.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Data; 7 | 8 | namespace SharpData { 9 | [DebuggerDisplay("[{Name}][{Value}]")] 10 | public class InOut { 11 | public string Name { get; set; } 12 | public object Value { get; set; } 13 | public DbType Type { get; set; } 14 | public int Size { get; set; } 15 | 16 | public static InOut Par(string name, DbType type) { return new InOut() { Name = name, Type = type, Size = 4000 }; } 17 | public static InOut Par(string name, DbType type, int size) { return new InOut() { Name = name, Type = type, Size = size }; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SharpData/Log/SharpDataLogging.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Logging; 2 | 3 | namespace SharpData.Log { 4 | public static class SharpDataLogging { 5 | public static ILoggerFactory LoggerFactory { get; set; } = new LoggerFactory(); 6 | public static ILogger CreateLogger() => LoggerFactory.CreateLogger(); 7 | public static ILogger CreateLogger(string category) => LoggerFactory.CreateLogger(category); 8 | } 9 | } -------------------------------------------------------------------------------- /SharpData/Out.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Data; 7 | 8 | namespace SharpData { 9 | [DebuggerDisplay("[{Name}][{Value}]")] 10 | public class Out { 11 | 12 | public string Name { get; set; } 13 | public object Value { get; set; } 14 | public DbType Type { get; set; } 15 | public int Size { get; set; } 16 | public bool IsCursor { get; set; } 17 | 18 | public static Out Cursor { get { return new Out { IsCursor = true }; } } 19 | public static Out Par(string name, DbType type) { return new Out { Name = name, Type = type, Size = 4000 }; } 20 | public static Out Par(string name, DbType type, int size) { return new Out { Name = name, Type = type, Size = size }; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SharpData/ResultSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SharpData { 5 | public class ResultSet : List { 6 | private List _originalColumnNames; 7 | private Dictionary _cols; 8 | 9 | public ResultSet(params string[] cols) { 10 | _cols = new Dictionary(); 11 | _originalColumnNames = new List(); 12 | 13 | for (int i = 0; i < cols.Length; i++) { 14 | SetColumnName(cols[i], i); 15 | } 16 | } 17 | 18 | private void SetColumnName(string col, int order) { 19 | if (_cols.ContainsKey(col.ToUpper())) { 20 | col+="_" + order; 21 | } 22 | _originalColumnNames.Add(col); 23 | _cols.Add(col.ToUpper(), order); 24 | } 25 | 26 | public void AddRow(params object[] row) { 27 | if (row.Length != _cols.Keys.Count) { 28 | throw new ArgumentException("Wrong number of columns in row"); 29 | } 30 | Add(new TableRow(this,row)); 31 | } 32 | 33 | public int GetColumnIndex(string colName) { 34 | return _cols[colName.ToUpper()]; 35 | } 36 | 37 | public string[] GetColumnNames() { 38 | return _originalColumnNames.ToArray(); 39 | } 40 | 41 | public bool IsEmpty { 42 | get { return Count == 0; } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /SharpData/ResultSetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using SharpData.Util; 6 | 7 | namespace SharpData { 8 | public static class ResultSetExtensions { 9 | public static List Map(this ResultSet res) where T : new() { 10 | var list = new List(); 11 | Type type = typeof(T); 12 | var columns = res.GetColumnNames(); 13 | var columnProps = columns.Select(x => type.GetProperty(x, ReflectionHelper.NoRestrictions | BindingFlags.IgnoreCase)) 14 | .ToList(); 15 | foreach (var row in res) { 16 | var obj = new T(); 17 | for (int i = 0; i < columnProps.Count; i++) { 18 | var propertyInfo = columnProps[i]; 19 | if (propertyInfo == null) { 20 | continue; 21 | } 22 | object value = row[i]; 23 | var targetType = IsNullableType(propertyInfo.PropertyType) ? 24 | Nullable.GetUnderlyingType(propertyInfo.PropertyType) : 25 | propertyInfo.PropertyType; 26 | 27 | if(value != null) { 28 | if (targetType.GetTypeInfo().IsEnum) { 29 | value = Enum.ToObject(targetType, value); 30 | } 31 | else if (value.GetType() != targetType) { 32 | value = Convert.ChangeType(value, targetType); 33 | } 34 | } 35 | propertyInfo.SetValue(obj, value, null); 36 | } 37 | list.Add(obj); 38 | 39 | } 40 | return list; 41 | } 42 | 43 | private static bool IsNullableType(Type type) { 44 | var typeInfo = type.GetTypeInfo(); 45 | return typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /SharpData/Schema/Column.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace SharpData.Schema { 4 | public class Column { 5 | 6 | public DbType Type { get; set; } 7 | public string ColumnName { get; set; } 8 | public int Size { get; set; } 9 | public bool IsNullable { get; set; } 10 | public object DefaultValue { get; set; } 11 | public string Comment { get; set; } 12 | 13 | private bool _isPrimaryKey; 14 | public bool IsPrimaryKey { 15 | get => _isPrimaryKey; 16 | set { 17 | _isPrimaryKey = value; 18 | if (_isPrimaryKey) { 19 | IsNullable = false; 20 | } 21 | } 22 | } 23 | 24 | private bool _isAutoIncrement; 25 | public bool IsAutoIncrement { 26 | get => _isAutoIncrement; 27 | set { 28 | _isAutoIncrement = value; 29 | if (_isAutoIncrement) { 30 | IsNullable = false; 31 | } 32 | } 33 | } 34 | 35 | public Column(string name, DbType type = DbType.String) { 36 | ColumnName = name; 37 | IsAutoIncrement = false; 38 | Type = type; 39 | IsNullable = true; 40 | } 41 | 42 | public static FluentColumn AutoIncrement(string name) { 43 | var fc = new FluentColumn(name, DbType.Int32); 44 | fc.Object.IsAutoIncrement = true; 45 | return fc; 46 | } 47 | public static FluentColumn AnsiString(string name, int size = 0) { return new FluentColumn(name, DbType.AnsiString, size); } 48 | public static FluentColumn String(string name, int size = 0) { return new FluentColumn(name, DbType.String, size); } 49 | public static FluentColumn Clob(string name, int size = System.Int32.MaxValue) { return new FluentColumn(name, DbType.String, size); } 50 | public static FluentColumn Binary(string name, int size = System.Int32.MaxValue) { return new FluentColumn(name, DbType.Binary, size); } 51 | public static FluentColumn Int16(string name) { return new FluentColumn(name, DbType.Int16); } 52 | public static FluentColumn Int32(string name) { return new FluentColumn(name, DbType.Int32); } 53 | public static FluentColumn Int64(string name) { return new FluentColumn(name, DbType.Int64); } 54 | public static FluentColumn Boolean(string name) { return new FluentColumn(name, DbType.Boolean); } 55 | public static FluentColumn Date(string name) { return new FluentColumn(name, DbType.Date); } 56 | public static FluentColumn Decimal(string name) { return new FluentColumn(name, DbType.Decimal); } 57 | public static FluentColumn Single(string name) { return new FluentColumn(name, DbType.Single); } 58 | public static FluentColumn Double(string name) { return new FluentColumn(name, DbType.Double); } 59 | public static FluentColumn Guid(string name) { return new FluentColumn(name, DbType.Guid); } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SharpData/Schema/FluentColumn.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace SharpData.Schema { 4 | public class FluentColumn { 5 | 6 | public Column Object { get; protected set; } 7 | 8 | public FluentColumn(string name, DbType type) : this(name, type, -1) { } 9 | 10 | public FluentColumn(string name, DbType type = DbType.String, int size = -1) { 11 | Object = new Column(name, type); 12 | if (size > 0) { 13 | Object.Size = size; 14 | } 15 | } 16 | 17 | public FluentColumn Size(int size) { 18 | Object.Size = size; 19 | return this; 20 | } 21 | 22 | public FluentColumn NotNull() { 23 | Object.IsNullable = false; 24 | return this; 25 | } 26 | 27 | public FluentColumn AsPrimaryKey() { 28 | Object.IsPrimaryKey = true; 29 | return this; 30 | } 31 | 32 | public FluentColumn DefaultValue(object value) { 33 | Object.DefaultValue = value; 34 | return this; 35 | } 36 | 37 | public FluentColumn Comment(string comment) { 38 | Object.Comment = comment; 39 | return this; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /SharpData/Schema/OnDelete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SharpData.Schema { 7 | public enum OnDelete { 8 | NoAction, 9 | Cascade, 10 | SetNull 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SharpData/Schema/OrderBy.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Schema { 2 | public class OrderBy { 3 | public string ColumnName { get; set; } 4 | public OrderByDirection Direction { get; set; } 5 | 6 | public static OrderBy Ascending(string columnName) { 7 | return new OrderBy {ColumnName = columnName, Direction = OrderByDirection.Ascending }; 8 | } 9 | 10 | public static OrderBy Descending(string columnName) { 11 | return new OrderBy { ColumnName = columnName, Direction = OrderByDirection.Descending }; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /SharpData/Schema/OrderByDirection.cs: -------------------------------------------------------------------------------- 1 | namespace SharpData.Schema { 2 | public enum OrderByDirection { 3 | Ascending, 4 | Descending 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SharpData/Schema/Table.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SharpData.Schema { 4 | 5 | public class Table { 6 | 7 | public string Name { get; protected set; } 8 | public List Columns { get; protected set; } 9 | 10 | public Table(string name) { 11 | Name = name; 12 | Columns = new List(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /SharpData/SharpData.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;net46 5 | 2.1.1 6 | Andre Carlucci 7 | Andre Carlucci 8 | An awesome ORM for querying and modifying databases. 9 | https://github.com/SharpTools/sharpdata 10 | https://raw.githubusercontent.com/SharpTools/sharpdata/master/LICENSE 11 | orm, netstandard, migrations, .netcore, databases 12 | True 13 | 14 | 15 | 16 | 17 | 7.1 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /SharpData/SharpDbConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpData { 4 | public class SharpDbConfig { 5 | public string DbProviderName { get; set; } 6 | public IDataProvider DataProvider { get; set; } 7 | public Database Database { get; set; } 8 | public DataClient DataClient { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /SharpData/SharpFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using SharpData.Databases; 4 | using SharpData.Databases.MySql; 5 | using SharpData.Databases.Oracle; 6 | using SharpData.Databases.PostgreSql; 7 | using SharpData.Databases.SqLite; 8 | using SharpData.Databases.SqlServer; 9 | using System.Data.Common; 10 | using SharpData.Exceptions; 11 | 12 | namespace SharpData { 13 | public class SharpFactory : ISharpFactory { 14 | 15 | public string ConnectionString { get; set; } 16 | public DbProviderFactory DbProviderFactory { get; set; } 17 | 18 | private static Dictionary _dbFactoryTypes = new Dictionary { 19 | {DbProviderType.OracleManaged, typeof(OracleManagedDbFactory)}, 20 | {DbProviderType.OracleOdp, typeof(OracleOdpDbFactory)}, 21 | {DbProviderType.MySql, typeof(MySqlDbFactory)}, 22 | {DbProviderType.OleDb, typeof(OleDbDbFactory)}, 23 | {DbProviderType.SqLite, typeof(SqLiteDbFactory)}, 24 | {DbProviderType.SqlServer, typeof(SqlServerDbFactory)}, 25 | {DbProviderType.PostgreSql, typeof(PostgreDbFactory)} 26 | }; 27 | private Dictionary _dbFactories = new Dictionary(); 28 | 29 | public SharpFactory(DbProviderFactory dbProviderFactory, string connectionString) { 30 | ConnectionString = connectionString; 31 | DbProviderFactory = dbProviderFactory; 32 | } 33 | 34 | public IDataProvider CreateDataProvider() { 35 | return GetConfig(DbProviderFactory).CreateDataProvider(); 36 | } 37 | 38 | public IDatabase CreateDatabase() { 39 | return GetConfig(DbProviderFactory, ConnectionString).CreateDatabase(); 40 | } 41 | 42 | public IDataClient CreateDataClient() { 43 | return GetConfig(DbProviderFactory, ConnectionString).CreateDataClient(); 44 | } 45 | 46 | public Dialect CreateDialect() { 47 | return GetConfig(DbProviderFactory).CreateDialect(); 48 | } 49 | 50 | private DbFactory GetConfig(DbProviderFactory dbProviderFactory) { 51 | return GetConfig(dbProviderFactory, ConnectionString); 52 | } 53 | 54 | private DbFactory GetConfig(DbProviderFactory dbProviderFactory, string connectionString) { 55 | var dbProviderType = GetDbProviderType(dbProviderFactory); 56 | EnsureProvider(dbProviderType); 57 | EnsureProviderInstance(dbProviderFactory, connectionString); 58 | return _dbFactories[dbProviderType]; 59 | } 60 | 61 | private DbProviderType GetDbProviderType(DbProviderFactory dbProviderFactory) { 62 | var name = dbProviderFactory.GetType().Namespace; 63 | return DbProviderTypeExtensions.GetDbProviderByNamespace(name); 64 | } 65 | 66 | private void EnsureProvider(DbProviderType databaseProviderName) { 67 | lock (_sync) { 68 | if (!_dbFactoryTypes.ContainsKey(databaseProviderName)) { 69 | throw new ProviderNotFoundException("SharpData does not support provider " + databaseProviderName); 70 | } 71 | } 72 | } 73 | 74 | private void EnsureProviderInstance(DbProviderFactory dbProviderFactory, string connectionString) { 75 | var databaseProviderName = GetDbProviderType(dbProviderFactory); 76 | lock (_sync) { 77 | if (!_dbFactories.ContainsKey(databaseProviderName)) { 78 | _dbFactories.Add(databaseProviderName, (DbFactory)Activator.CreateInstance(_dbFactoryTypes[databaseProviderName], dbProviderFactory, connectionString)); 79 | return; 80 | } 81 | _dbFactories[databaseProviderName].ConnectionString = connectionString; 82 | } 83 | 84 | } 85 | 86 | public static ISharpFactory Default {get; set; } 87 | private static object _sync = new object(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /SharpData/TableRow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SharpData { 4 | public class TableRow : List { 5 | 6 | protected ResultSet _table; 7 | 8 | public TableRow(ResultSet table, IEnumerable values) { 9 | _table = table; 10 | AddRange(values); 11 | } 12 | 13 | public object this[string col] { 14 | get { 15 | return this[_table.GetColumnIndex(col)]; 16 | } 17 | } 18 | 19 | public string[] GetColumnNames() { 20 | return _table.GetColumnNames(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /SharpData/Util/IntExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SharpData.Util { 7 | public static class IntExtensions { 8 | 9 | public static bool Between(this Int32 value, int smaller, int bigger) { 10 | return value >= smaller && value <= bigger; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SharpData/Util/ReflectionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Reflection; 5 | 6 | namespace SharpData.Util { 7 | public class ReflectionHelper { 8 | public static BindingFlags NoRestrictions = BindingFlags.Public | 9 | BindingFlags.NonPublic | 10 | BindingFlags.Static | 11 | BindingFlags.Instance; 12 | 13 | public static string[] GetPropertiesNames(Type type) => 14 | type.GetProperties(NoRestrictions | BindingFlags.IgnoreCase) 15 | .Select(p => p.Name) 16 | .ToArray(); 17 | 18 | public static object[] GetPropertiesValues(object obj) => 19 | obj.GetType() 20 | .GetProperties(NoRestrictions | BindingFlags.IgnoreCase) 21 | .Select(p => p.GetValue(obj)) 22 | .ToArray(); 23 | 24 | public static LambdaExpression StripConvert(Expression> source) { 25 | var result = source.Body; 26 | while (((result.NodeType == ExpressionType.Convert) 27 | || (result.NodeType == ExpressionType.ConvertChecked)) 28 | && (result.Type == typeof(object))) { 29 | result = ((UnaryExpression)result).Operand; 30 | } 31 | return Expression.Lambda(result, source.Parameters); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /SharpData/Util/StringHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Sharp.Util { 5 | 6 | //public static class StringHelper { 7 | 8 | // public static string Implode(String[] value, string separator) { 9 | // StringBuilder sb = new StringBuilder(); 10 | // for (int i = 0; i < value.Length; i++) { 11 | // sb.Append(value[i]); 12 | // if (i != value.Length - 1) { 13 | // sb.Append(separator); 14 | // } 15 | // } 16 | // return sb.ToString(); 17 | // } 18 | //} 19 | } 20 | --------------------------------------------------------------------------------