From 0bba0017ff2c7eb67d74ab812f3c07759d5be6f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 15:35:09 +0000 Subject: [PATCH 1/7] Bump HIC.TypeGuesser from 1.1.0 to 1.2.1 Bumps [HIC.TypeGuesser](https://github.com/HicServices/TypeGuesser) from 1.1.0 to 1.2.1. - [Release notes](https://github.com/HicServices/TypeGuesser/releases) - [Changelog](https://github.com/HicServices/TypeGuesser/blob/main/CHANGELOG.md) - [Commits](https://github.com/HicServices/TypeGuesser/compare/1.1.0...v1.2.1) --- updated-dependencies: - dependency-name: HIC.TypeGuesser dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- FAnsiSql/FAnsi.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FAnsiSql/FAnsi.csproj b/FAnsiSql/FAnsi.csproj index 36fd9420..81309e7a 100644 --- a/FAnsiSql/FAnsi.csproj +++ b/FAnsiSql/FAnsi.csproj @@ -37,7 +37,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From 2ec6d9c5f8c163c637d339e524fe73d5ed9255fe Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 30 Jan 2024 15:06:26 -0600 Subject: [PATCH 2/7] Syntax clean --- FAnsiSql/Connections/ManagedConnection.cs | 5 +- FAnsiSql/DatabaseOperationArgs.cs | 16 +- FAnsiSql/Discovery/BulkCopy.cs | 7 +- .../ConnectionStringKeywordAccumulator.cs | 2 - .../RelationshipTopologicalSort.cs | 2 - FAnsiSql/Discovery/DatabaseColumnRequest.cs | 10 +- FAnsiSql/Discovery/DiscoveredColumn.cs | 36 +--- FAnsiSql/Discovery/DiscoveredDataType.cs | 30 +--- FAnsiSql/Discovery/DiscoveredDatabase.cs | 64 ++----- .../Discovery/DiscoveredDatabaseHelper.cs | 21 +-- FAnsiSql/Discovery/DiscoveredServer.cs | 60 ++----- FAnsiSql/Discovery/DiscoveredServerHelper.cs | 5 +- FAnsiSql/Discovery/DiscoveredTable.cs | 130 +++++--------- FAnsiSql/Discovery/DiscoveredTableHelper.cs | 7 +- .../DiscoveredTableValuedFunction.cs | 12 +- FAnsiSql/Discovery/QuerySyntax/CustomLine.cs | 5 +- .../QuerySyntax/QuerySyntaxHelperFactory.cs | 5 +- FAnsiSql/Discovery/QuerySyntaxHelper.cs | 80 ++------- .../TypeTranslation/TypeTranslater.cs | 159 +++++------------- FAnsiSql/Extensions/DataColumnExtensions.cs | 10 +- FAnsiSql/FAnsi.csproj | 7 +- .../Implementation/ImplementationManager.cs | 10 +- .../MicrosoftQuerySyntaxHelper.cs | 45 +---- .../MicrosoftSQL/MicrosoftSQLBulkCopy.cs | 2 - .../MicrosoftSQLDatabaseHelper.cs | 7 +- .../MicrosoftSQL/MicrosoftSQLServerHelper.cs | 51 ++---- .../MicrosoftSQL/MicrosoftSQLTableHelper.cs | 20 +-- .../MySql/MySqlDatabaseHelper.cs | 5 +- .../MySql/MySqlQuerySyntaxHelper.cs | 19 +-- .../Implementations/MySql/MySqlTableHelper.cs | 14 +- .../MySql/MySqlTypeTranslater.cs | 31 +--- .../Aggregation/OracleAggregateHelper.cs | 10 +- .../Implementations/Oracle/OracleBulkCopy.cs | 34 ++-- .../Oracle/OracleDatabaseHelper.cs | 34 +--- .../Oracle/OracleQuerySyntaxHelper.cs | 54 ++---- .../Oracle/OracleServerHelper.cs | 37 +--- .../Oracle/OracleTableHelper.cs | 19 +-- .../Oracle/OracleTypeTranslater.cs | 13 +- .../PostgreSql/PostgreSqlDatabaseHelper.cs | 18 +- .../PostgreSql/PostgreSqlServerHelper.cs | 51 ++---- .../PostgreSql/PostgreSqlSyntaxHelper.cs | 58 ++----- .../PostgreSql/PostgreSqlTableHelper.cs | 10 +- .../Aggregation/AggregationTests.cs | 3 - Tests/FAnsiTests/CrossPlatformTests.cs | 2 - Tests/FAnsiTests/DatabaseTests.cs | 2 - .../Query/QuerySyntaxHelperTests.cs | 2 - Tests/FAnsiTests/Table/BulkInsertTest.cs | 6 +- Tests/FAnsiTests/Table/TableTypeTests.cs | 5 +- .../TypeTranslation/GuesserExtensions.cs | 5 +- .../TypeTranslation/TypeTranslaterTests.cs | 2 - 50 files changed, 301 insertions(+), 941 deletions(-) diff --git a/FAnsiSql/Connections/ManagedConnection.cs b/FAnsiSql/Connections/ManagedConnection.cs index d27658d2..7fc8166a 100644 --- a/FAnsiSql/Connections/ManagedConnection.cs +++ b/FAnsiSql/Connections/ManagedConnection.cs @@ -37,10 +37,7 @@ internal ManagedConnection(DiscoveredServer discoveredServer, IManagedTransactio Connection.Open(); } - public ManagedConnection Clone() - { - return (ManagedConnection) MemberwiseClone(); - } + public ManagedConnection Clone() => (ManagedConnection) MemberwiseClone(); /// /// Closes and disposes the DbConnection unless this class is part of an diff --git a/FAnsiSql/DatabaseOperationArgs.cs b/FAnsiSql/DatabaseOperationArgs.cs index e2eb73da..fd97f0aa 100644 --- a/FAnsiSql/DatabaseOperationArgs.cs +++ b/FAnsiSql/DatabaseOperationArgs.cs @@ -130,10 +130,7 @@ private void Hydrate(DbCommand cmd) /// /// /// - public IManagedConnection GetManagedConnection(DiscoveredTable table) - { - return GetManagedConnection(table.Database.Server); - } + public IManagedConnection GetManagedConnection(DiscoveredTable table) => GetManagedConnection(table.Database.Server); /// /// Opens a new connection or passes back an existing opened connection (that matches @@ -141,10 +138,7 @@ public IManagedConnection GetManagedConnection(DiscoveredTable table) /// /// /// - public IManagedConnection GetManagedConnection(DiscoveredDatabase database) - { - return GetManagedConnection(database.Server); - } + public IManagedConnection GetManagedConnection(DiscoveredDatabase database) => GetManagedConnection(database.Server); /// /// Opens a new connection or passes back an existing opened connection (that matches @@ -152,9 +146,5 @@ public IManagedConnection GetManagedConnection(DiscoveredDatabase database) /// /// /// - public IManagedConnection GetManagedConnection(DiscoveredServer server) - { - return server.GetManagedConnection(TransactionIfAny); - } - + public IManagedConnection GetManagedConnection(DiscoveredServer server) => server.GetManagedConnection(TransactionIfAny); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/BulkCopy.cs b/FAnsiSql/Discovery/BulkCopy.cs index a3dbe869..5206d9df 100644 --- a/FAnsiSql/Discovery/BulkCopy.cs +++ b/FAnsiSql/Discovery/BulkCopy.cs @@ -130,7 +130,6 @@ protected void ConvertStringTypesToHardTypes(DataTable dt) foreach(DataRow dr in dt.Rows) - { try { //parse the value @@ -141,7 +140,6 @@ protected void ConvertStringTypesToHardTypes(DataTable dt) { throw new Exception($"Failed to parse value '{dr[dataColumn]}' in column '{dataColumn}'",ex); } - } //if the DataColumn is part of the Primary Key of the DataTable (in memory) //then we need to update the primary key to include the new column not the old one @@ -201,8 +199,5 @@ protected Dictionary GetMapping(IEnumerable /// /// - protected Dictionary GetMapping(IEnumerable inputColumns) - { - return GetMapping(inputColumns, out _); - } + protected Dictionary GetMapping(IEnumerable inputColumns) => GetMapping(inputColumns, out _); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs b/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs index 7550ec77..2bdc6386 100644 --- a/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs +++ b/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs @@ -50,10 +50,8 @@ public void AddOrUpdateKeyword(string keyword, string value, ConnectionStringKey //if we have not got that keyword yet if(!_keywords.TryAdd(keyword, Tuple.Create(value, priority)) && _keywords[keyword].Item2 <= priority) - { //or the keyword that was previously specified had a lower priority _keywords[keyword] = Tuple.Create(value, priority); //update it with the new value - } } /// diff --git a/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs b/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs index 97ccd223..97d5dc09 100644 --- a/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs +++ b/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs @@ -78,10 +78,8 @@ private static List TopologicalSort(IEnumerable nodes, HashSet !me.Item2.Equals(m))) - { // insert m into S s.Add(m); - } } } diff --git a/FAnsiSql/Discovery/DatabaseColumnRequest.cs b/FAnsiSql/Discovery/DatabaseColumnRequest.cs index 674de20e..aec0858a 100644 --- a/FAnsiSql/Discovery/DatabaseColumnRequest.cs +++ b/FAnsiSql/Discovery/DatabaseColumnRequest.cs @@ -69,13 +69,7 @@ public DatabaseColumnRequest(string columnName, string explicitDbType, bool allo /// /// /// - public string GetSQLDbType(ITypeTranslater typeTranslater) - { - return ExplicitDbType??typeTranslater.GetSQLDBTypeForCSharpType(TypeRequested); - } + public string GetSQLDbType(ITypeTranslater typeTranslater) => ExplicitDbType??typeTranslater.GetSQLDBTypeForCSharpType(TypeRequested); - public string GetRuntimeName() - { - return ColumnName; - } + public string GetRuntimeName() => ColumnName; } \ No newline at end of file diff --git a/FAnsiSql/Discovery/DiscoveredColumn.cs b/FAnsiSql/Discovery/DiscoveredColumn.cs index 9a61560c..f3b5ab1d 100644 --- a/FAnsiSql/Discovery/DiscoveredColumn.cs +++ b/FAnsiSql/Discovery/DiscoveredColumn.cs @@ -63,19 +63,13 @@ public sealed class DiscoveredColumn(DiscoveredTable table, string name, bool al /// The unqualified name of the column e.g. "MyCol" /// /// - public string GetRuntimeName() - { - return _querySyntaxHelper.GetRuntimeName(_name); - } + public string GetRuntimeName() => _querySyntaxHelper.GetRuntimeName(_name); /// /// The fully qualified name of the column e.g. [MyDb].dbo.[MyTable].[MyCol] or `MyDb`.`MyCol` /// /// - public string GetFullyQualifiedName() - { - return _querySyntaxHelper.EnsureFullyQualified(Table.Database.GetRuntimeName(),Table.Schema, Table.GetRuntimeName(), GetRuntimeName(), Table is DiscoveredTableValuedFunction); - } + public string GetFullyQualifiedName() => _querySyntaxHelper.EnsureFullyQualified(Table.Database.GetRuntimeName(),Table.Schema, Table.GetRuntimeName(), GetRuntimeName(), Table is DiscoveredTableValuedFunction); /// @@ -84,39 +78,28 @@ public string GetFullyQualifiedName() /// The number of records to return /// If true adds a WHERE statement to throw away null values /// - public string GetTopXSql(int topX, bool discardNulls) - { - return Helper.GetTopXSqlForColumn(Table.Database, Table, this, topX, discardNulls); - } + public string GetTopXSql(int topX, bool discardNulls) => Helper.GetTopXSqlForColumn(Table.Database, Table, this, topX, discardNulls); /// /// Returns the name of the column /// /// - public override string ToString() - { - return _name; - } + public override string ToString() => _name; /// /// Generates a primed with the of this column. This can be used to inspect new /// untyped (string) data to determine whether it will fit into the column. /// /// - public Guesser GetGuesser() - { - return Table.GetQuerySyntaxHelper().TypeTranslater.GetGuesserFor(this); - } + public Guesser GetGuesser() => Table.GetQuerySyntaxHelper().TypeTranslater.GetGuesserFor(this); /// /// Based on column name and Table /// /// /// - private bool Equals(DiscoveredColumn other) - { - return string.Equals(_name, other._name) && Equals(Table, other.Table); - } + private bool Equals(DiscoveredColumn other) => string.Equals(_name, other._name) && Equals(Table, other.Table); + /// /// Based on column name and Table /// @@ -147,8 +130,5 @@ public override int GetHashCode() /// Returns the wrapped e.g. "[MyCol]" name of the column including escaping e.g. if you wanted to name a column "][nquisitor" (which would return "[]][nquisitor]"). Use to return the full name including table/database/schema. /// /// - public string GetWrappedName() - { - return Table.GetQuerySyntaxHelper().EnsureWrapped(GetRuntimeName()); - } + public string GetWrappedName() => Table.GetQuerySyntaxHelper().EnsureWrapped(GetRuntimeName()); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/DiscoveredDataType.cs b/FAnsiSql/Discovery/DiscoveredDataType.cs index 2144813d..eea36229 100644 --- a/FAnsiSql/Discovery/DiscoveredDataType.cs +++ b/FAnsiSql/Discovery/DiscoveredDataType.cs @@ -46,10 +46,7 @@ public DiscoveredDataType(DbDataReader r, string sqlType, DiscoveredColumn colum /// Returns if the string type has no real limit e.g. "text" /// /// - public int GetLengthIfString() - { - return Column.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetLengthIfString(SQLType); - } + public int GetLengthIfString() => Column.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetLengthIfString(SQLType); /// /// Returns the Scale/Precision of the data type. Only applies to decimal(x,y) types not basic types e.g. int. @@ -57,29 +54,20 @@ public int GetLengthIfString() /// Returns null if the datatype is not floating point /// /// - public DecimalSize GetDecimalSize() - { - return Column.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetDigitsBeforeAndAfterDecimalPointIfDecimal(SQLType); - } + public DecimalSize GetDecimalSize() => Column.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetDigitsBeforeAndAfterDecimalPointIfDecimal(SQLType); /// /// Returns the System.Type that should be used to store values read out of columns of this data type (See /// /// [return:DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties|DynamicallyAccessedMemberTypes.PublicFields)] - public Type GetCSharpDataType() - { - return Column.Table.Database.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(SQLType); - } + public Type GetCSharpDataType() => Column.Table.Database.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(SQLType); /// /// Returns the /// /// - public override string ToString() - { - return SQLType; - } + public override string ToString() => SQLType; /// /// Creates and runs an ALTER TABLE statement which will increase the size of a char column to support longer string values than it currently does. @@ -174,19 +162,13 @@ public void AlterTypeTo(string newType, IManagedTransaction managedTransaction = /// /// /// - private bool Equals(DiscoveredDataType other) - { - return string.Equals(SQLType, other.SQLType); - } + private bool Equals(DiscoveredDataType other) => string.Equals(SQLType, other.SQLType); /// /// Equality based on /// /// - public override int GetHashCode() - { - return SQLType != null ? SQLType.GetHashCode() : 0; - } + public override int GetHashCode() => SQLType != null ? SQLType.GetHashCode() : 0; /// /// Equality based on diff --git a/FAnsiSql/Discovery/DiscoveredDatabase.cs b/FAnsiSql/Discovery/DiscoveredDatabase.cs index 92e69f9c..9eab475b 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabase.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabase.cs @@ -78,19 +78,13 @@ public IEnumerable DiscoverTableValuedFunctions(I /// Returns the name of the database without any qualifiers /// /// - public string GetRuntimeName() - { - return _querySyntaxHelper.GetRuntimeName(_database); - } + public string GetRuntimeName() => _querySyntaxHelper.GetRuntimeName(_database); /// /// Returns the wrapped e.g. "[MyDatabase]" name of the database including escaping e.g. if you wanted to name a database "][nquisitor" (which would return "[]][nquisitor]"). /// /// - public string GetWrappedName() - { - return _querySyntaxHelper.EnsureWrapped(GetRuntimeName()); - } + public string GetWrappedName() => _querySyntaxHelper.EnsureWrapped(GetRuntimeName()); /// /// Creates an expectation (See ) that there is a table with the given name in the database. @@ -112,28 +106,19 @@ public DiscoveredTable ExpectTable(string tableName, string schema = null, Table } /// - public DiscoveredTableValuedFunction ExpectTableValuedFunction(string tableName,string schema = null) - { - return new DiscoveredTableValuedFunction(this, tableName, _querySyntaxHelper, schema); - } + public DiscoveredTableValuedFunction ExpectTableValuedFunction(string tableName,string schema = null) => new(this, tableName, _querySyntaxHelper, schema); /// /// Connects to the database and returns a list of stored proceedures found as objects /// /// - public DiscoveredStoredprocedure[] DiscoverStoredprocedures() - { - return Helper.ListStoredprocedures(Server.Builder,GetRuntimeName()); - } + public DiscoveredStoredprocedure[] DiscoverStoredprocedures() => Helper.ListStoredprocedures(Server.Builder,GetRuntimeName()); /// /// Returns the name of the database /// /// - public override string ToString() - { - return _database; - } + public override string ToString() => _database; /// /// Connects to the server and enumerates the databases to see whether the currently described database exists. @@ -161,10 +146,7 @@ public void Drop() /// Return key value pairs which describe attributes of the database e.g. available space, physical location etc. /// /// - public Dictionary DescribeDatabase() - { - return Helper.DescribeDatabase(Server.Builder, GetRuntimeName()); - } + public Dictionary DescribeDatabase() => Helper.DescribeDatabase(Server.Builder, GetRuntimeName()); /// /// Creates the database referenced by this object. @@ -187,14 +169,12 @@ public void Create(bool dropFirst = false) /// If in doubt leave blank /// Last minute delegate class for modifying the data types prior to executing SQL /// The table created - public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, string schema = null, IDatabaseColumnRequestAdjuster adjuster = null) - { - return CreateTable(new CreateTableArgs(this,tableName, schema) + public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, string schema = null, IDatabaseColumnRequestAdjuster adjuster = null) => + CreateTable(new CreateTableArgs(this,tableName, schema) { Adjuster = adjuster, ExplicitColumnDefinitions = columns }); - } /// /// Assembles and runs a CREATE TABLE sql statement and returns the table created as a . @@ -211,16 +191,13 @@ public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] col /// /// True to set CASCADE DELETE on the foreign key created by /// The table created - public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete, IDatabaseColumnRequestAdjuster adjuster = null) - { - return CreateTable(new CreateTableArgs(this, tableName, null, foreignKeyPairs, cascadeDelete) + public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete, IDatabaseColumnRequestAdjuster adjuster = null) => + CreateTable(new CreateTableArgs(this, tableName, null, foreignKeyPairs, cascadeDelete) { Adjuster = adjuster, ExplicitColumnDefinitions = columns }); - } - /// /// Assembles and runs a CREATE TABLE sql statement based on the data/columns in and returns the table created as a . /// @@ -232,22 +209,17 @@ public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] col /// Last minute delegate class for modifying the table columns data types prior to executing SQL /// Optional - Override descisions made about columns in the by specify an explicit type etc /// The table created - public DiscoveredTable CreateTable(string tableName, DataTable dt, DatabaseColumnRequest[] explicitColumnDefinitions = null, bool createEmpty = false,IDatabaseColumnRequestAdjuster adjuster = null) - { - return CreateTable(new CreateTableArgs(this, tableName, null,dt,createEmpty) + public DiscoveredTable CreateTable(string tableName, DataTable dt, DatabaseColumnRequest[] explicitColumnDefinitions = null, bool createEmpty = false,IDatabaseColumnRequestAdjuster adjuster = null) => + CreateTable(new CreateTableArgs(this, tableName, null,dt,createEmpty) { ExplicitColumnDefinitions = explicitColumnDefinitions, Adjuster = adjuster }); - } /// /// Assembles and runs a CREATE TABLE sql statement and returns the table created as a . /// - public DiscoveredTable CreateTable(CreateTableArgs args) - { - return Helper.CreateTable(args); - } + public DiscoveredTable CreateTable(CreateTableArgs args) => Helper.CreateTable(args); /// /// Creates a table in the database big enough to store the supplied DataTable with appropriate types. @@ -294,10 +266,7 @@ public void CreateSchema(string name) /// NOTE: you must know how to map this data path to a shared path you can access! /// /// Local drive data path where the files are stored - public DirectoryInfo Detach() - { - return Helper.Detach(this); - } + public DirectoryInfo Detach() => Helper.Detach(this); /// /// Creates a local (to the DBMS server) backup of the database. Implementations may vary but should be the simplest database type @@ -314,10 +283,7 @@ public void CreateBackup(string backupName) /// /// /// - private bool Equals(DiscoveredDatabase other) - { - return Equals(Server, other.Server) && string.Equals(_database, other._database,StringComparison.OrdinalIgnoreCase); - } + private bool Equals(DiscoveredDatabase other) => Equals(Server, other.Server) && string.Equals(_database, other._database,StringComparison.OrdinalIgnoreCase); /// /// Equality based on Server and database name diff --git a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs index 8fef353d..877d04b9 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs @@ -166,15 +166,9 @@ public void ThrowIfObjectColumns(DataTable dt) /// public abstract void CreateSchema(DiscoveredDatabase discoveredDatabase, string name); - protected virtual Guesser GetGuesser(DataColumn column) - { - return new Guesser(); - } + protected virtual Guesser GetGuesser(DataColumn column) => new(); - protected virtual Guesser GetGuesser(DatabaseTypeRequest request) - { - return new Guesser(request); - } + protected virtual Guesser GetGuesser(DatabaseTypeRequest request) => new(request); public virtual string GetCreateTableSql(DiscoveredDatabase database, string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete, string schema) { @@ -232,11 +226,7 @@ public virtual string GetCreateTableSql(DiscoveredDatabase database, string tabl /// /// /// - protected virtual string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) - { - return - $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} {(string.IsNullOrWhiteSpace(col.Collation) ? "" : $"COLLATE {col.Collation}")} {(col.AllowNulls && !col.IsPrimaryKey ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; - } + protected virtual string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) => $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} {(string.IsNullOrWhiteSpace(col.Collation) ? "" : $"COLLATE {col.Collation}")} {(col.AllowNulls && !col.IsPrimaryKey ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; public virtual string GetForeignKeyConstraintSql(string foreignTable, IQuerySyntaxHelper syntaxHelper, Dictionary foreignKeyPairs, bool cascadeDelete, string constraintName) @@ -252,10 +242,7 @@ public virtual string GetForeignKeyConstraintSql(string foreignTable, IQuerySynt REFERENCES {primaryKeyTable.GetFullyQualifiedName()}({string.Join(",", foreignKeyPairs.Values.Select(v => syntaxHelper.EnsureWrapped(v.GetRuntimeName())))}) {(cascadeDelete ? " on delete cascade" : "")} """; } - public string GetForeignKeyConstraintNameFor(DiscoveredTable foreignTable, DiscoveredTable primaryTable) - { - return GetForeignKeyConstraintNameFor(foreignTable.GetRuntimeName(), primaryTable.GetRuntimeName()); - } + public string GetForeignKeyConstraintNameFor(DiscoveredTable foreignTable, DiscoveredTable primaryTable) => GetForeignKeyConstraintNameFor(foreignTable.GetRuntimeName(), primaryTable.GetRuntimeName()); private static string GetForeignKeyConstraintNameFor(string foreignTable, string primaryTable) => MakeSensibleConstraintName("FK_", $"{foreignTable}_{primaryTable}"); diff --git a/FAnsiSql/Discovery/DiscoveredServer.cs b/FAnsiSql/Discovery/DiscoveredServer.cs index 7e0ef0e7..0392f4e0 100644 --- a/FAnsiSql/Discovery/DiscoveredServer.cs +++ b/FAnsiSql/Discovery/DiscoveredServer.cs @@ -107,10 +107,7 @@ public DiscoveredServer(string server,string database, DatabaseType databaseType /// /// Optional - when provided returns the instead of opening a new one /// - public DbConnection GetConnection(IManagedTransaction transaction = null) - { - return transaction != null ? transaction.Connection : Helper.GetConnection(Builder); - } + public DbConnection GetConnection(IManagedTransaction transaction = null) => transaction != null ? transaction.Connection : Helper.GetConnection(Builder); /// public DbCommand GetCommand(string sql, IManagedConnection managedConnection) @@ -143,10 +140,7 @@ public DbCommand GetCommand(string sql, DbConnection con, IManagedTransaction tr /// /// /// - private DbParameter GetParameter(string parameterName) - { - return Helper.GetParameter(parameterName); - } + private DbParameter GetParameter(string parameterName) => Helper.GetParameter(parameterName); /// /// Returns a new of the correct of the server. Also adds it @@ -232,10 +226,7 @@ public void TestConnection(int timeoutInMillis = 10000) /// /// /// - public bool RespondsWithinTime(int timeoutInSeconds, out Exception exception) - { - return Helper.RespondsWithinTime(Builder, timeoutInSeconds, out exception); - } + public bool RespondsWithinTime(int timeoutInSeconds, out Exception exception) => Helper.RespondsWithinTime(Builder, timeoutInSeconds, out exception); /// /// Connects to the server and returns a list of databases found as objects @@ -276,19 +267,13 @@ public bool Exists(IManagedTransaction transaction = null) /// /// /// - public DbDataAdapter GetDataAdapter(DbCommand cmd) - { - return Helper.GetDataAdapter(cmd); - } + public DbDataAdapter GetDataAdapter(DbCommand cmd) => Helper.GetDataAdapter(cmd); /// /// Returns a new correctly Typed for the /// /// - public DbDataAdapter GetDataAdapter(string command, DbConnection con) - { - return GetDataAdapter(GetCommand(command, con)); - } + public DbDataAdapter GetDataAdapter(string command, DbConnection con) => GetDataAdapter(GetCommand(command, con)); /// /// Returns the database that is currently pointed at. @@ -336,10 +321,7 @@ public void ChangeDatabase(string newDatabase) /// Returns the server /// /// - public override string ToString() - { - return Name ; - } + public override string ToString() => Name; /// /// Creates a new database with the given . @@ -366,10 +348,7 @@ public DiscoveredDatabase CreateDatabase(string newDatabaseName) /// should be wrapped with a using statement since it is . /// /// - public IManagedConnection BeginNewTransactedConnection() - { - return new ManagedConnection(this, Helper.BeginTransaction(Builder)){CloseOnDispose = true}; - } + public IManagedConnection BeginNewTransactedConnection() => new ManagedConnection(this, Helper.BeginTransaction(Builder)){CloseOnDispose = true}; /// /// Opens a new or reuses an existing one (if is provided). @@ -378,29 +357,20 @@ public IManagedConnection BeginNewTransactedConnection() /// /// /// - public IManagedConnection GetManagedConnection(IManagedTransaction transaction = null) - { - return new ManagedConnection(this, transaction); - } + public IManagedConnection GetManagedConnection(IManagedTransaction transaction = null) => new ManagedConnection(this, transaction); /// /// Returns helper for generating queries compatible with the DBMS (See ) e.g. TOP X, column qualifiers, what the parameter /// symbol is etc. /// /// - public IQuerySyntaxHelper GetQuerySyntaxHelper() - { - return Helper.GetQuerySyntaxHelper(); - } + public IQuerySyntaxHelper GetQuerySyntaxHelper() => Helper.GetQuerySyntaxHelper(); /// /// Return key value pairs which describe attributes of the server e.g. version, available drive space etc /// /// - public Dictionary DescribeServer() - { - return Helper.DescribeServer(Builder); - } + public Dictionary DescribeServer() => Helper.DescribeServer(Builder); /// /// Equality based on Builder.ConnectionString and DatabaseType @@ -434,17 +404,11 @@ public override bool Equals(object obj) /// Hashcode built from DatabaseType /// /// - public override int GetHashCode() - { - return DatabaseType.GetHashCode(); - } + public override int GetHashCode() => DatabaseType.GetHashCode(); /// /// Returns the version number of the DBMS e.g. MySql 5.7 /// /// - public Version GetVersion() - { - return Helper.GetVersion(this); - } + public Version GetVersion() => Helper.GetVersion(this); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/DiscoveredServerHelper.cs b/FAnsiSql/Discovery/DiscoveredServerHelper.cs index 634f2a04..427eb19d 100644 --- a/FAnsiSql/Discovery/DiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredServerHelper.cs @@ -95,10 +95,7 @@ public DbConnectionStringBuilder ChangeServer(DbConnectionStringBuilder builder, return builder; } - public virtual string GetCurrentDatabase(DbConnectionStringBuilder builder) - { - return (string) builder[DatabaseKeyName]; - } + public virtual string GetCurrentDatabase(DbConnectionStringBuilder builder) => (string) builder[DatabaseKeyName]; public virtual DbConnectionStringBuilder ChangeDatabase(DbConnectionStringBuilder builder, string newDatabase) { diff --git a/FAnsiSql/Discovery/DiscoveredTable.cs b/FAnsiSql/Discovery/DiscoveredTable.cs index 531cac32..04112ad8 100644 --- a/FAnsiSql/Discovery/DiscoveredTable.cs +++ b/FAnsiSql/Discovery/DiscoveredTable.cs @@ -17,36 +17,36 @@ namespace FAnsi.Discovery; /// Cross database type reference to a Table (or view) in a Database. Use TableType to determine whether it is a view or a table. Allows you to check /// existence, drop, add columns, get row counts etc. /// -public class DiscoveredTable :IHasFullyQualifiedNameToo, IMightNotExist, IHasQuerySyntaxHelper, IEquatable +public class DiscoveredTable : IHasFullyQualifiedNameToo, IMightNotExist, IHasQuerySyntaxHelper, IEquatable { - private string _table; + protected string TableName; /// /// Helper for generating queries compatible with the DBMS the table exists in (e.g. TOP X, column qualifiers, what the parameter symbol is etc). /// - protected IQuerySyntaxHelper QuerySyntaxHelper; + protected readonly IQuerySyntaxHelper QuerySyntaxHelper; /// /// The database on which the table exists /// - public DiscoveredDatabase Database { get; private set; } + public readonly DiscoveredDatabase Database; /// /// Stateless helper class with DBMS specific implementation of the logic required by . /// - public IDiscoveredTableHelper Helper { get; set; } + public readonly IDiscoveredTableHelper Helper; /// /// Schema of the the table exists in (or null). This is NOT the database e.g. in [MyDb].[dbo].[MyTable] the schema is "dbo". /// /// Null if not supported by the DBMS (e.g. MySql) /// - public string Schema { get; private set; } + public readonly string Schema; /// - /// Whether the table referenced is a normal table, view or table valued function (see derrived class ) + /// Whether the table referenced is a normal table, view or table valued function (see derived class ) /// - public TableType TableType { get; private set; } + public readonly TableType TableType; /// /// Internal API constructor intended for Implementation classes, instead use instead. @@ -58,7 +58,7 @@ public class DiscoveredTable :IHasFullyQualifiedNameToo, IMightNotExist, IHasQue /// public DiscoveredTable(DiscoveredDatabase database, string table, IQuerySyntaxHelper querySyntaxHelper, string schema = null, TableType tableType = TableType.Table) { - _table = table; + TableName = table; Helper = database.Helper.GetTableHelper(); Database = database; Schema = schema; @@ -66,7 +66,7 @@ public DiscoveredTable(DiscoveredDatabase database, string table, IQuerySyntaxHe QuerySyntaxHelper = querySyntaxHelper; - QuerySyntaxHelper.ValidateTableName(_table); + QuerySyntaxHelper.ValidateTableName(TableName); } /// @@ -81,35 +81,27 @@ public virtual bool Exists(IManagedTransaction transaction = null) return false; return Database.DiscoverTables(TableType == TableType.View, transaction) - .Any(t => t.GetRuntimeName().Equals(GetRuntimeName(),StringComparison.InvariantCultureIgnoreCase)); + .Any(t => t.GetRuntimeName().Equals(GetRuntimeName(), StringComparison.InvariantCultureIgnoreCase)); } /// /// Returns the unqualified name of the table e.g. "MyTable" /// /// - public virtual string GetRuntimeName() - { - return QuerySyntaxHelper.GetRuntimeName(_table); - } + public virtual string GetRuntimeName() => QuerySyntaxHelper.GetRuntimeName(TableName); /// /// Returns the fully qualified (including schema if appropriate) name of the table e.g. [MyDb].dbo.[MyTable] or `MyDb`.`MyTable` /// /// - public virtual string GetFullyQualifiedName() - { - return QuerySyntaxHelper.EnsureFullyQualified(Database.GetRuntimeName(),Schema, GetRuntimeName()); - } + public virtual string GetFullyQualifiedName() => QuerySyntaxHelper.EnsureFullyQualified(Database.GetRuntimeName(),Schema, GetRuntimeName()); /// /// Returns the wrapped e.g. "[MyTbl]" name of the table including escaping e.g. if you wanted to name a table "][nquisitor" (which would return "[]][nquisitor]"). Use to return the full name including table/database/schema. /// /// - public string GetWrappedName() - { - return QuerySyntaxHelper.EnsureWrapped(GetRuntimeName()); - } + public string GetWrappedName() => QuerySyntaxHelper.EnsureWrapped(GetRuntimeName()); + /// /// Connects to the server and returns a list of columns found in the table as . /// @@ -126,19 +118,13 @@ public DiscoveredColumn[] DiscoverColumns(IManagedTransaction managedTransaction /// Returns the table name /// /// - public override string ToString() - { - return _table; - } + public override string ToString() => TableName; /// /// Gets helper for generating queries compatible with the DBMS the table exists in (e.g. TOP X, column qualifiers, what the parameter symbol is etc). /// /// - public IQuerySyntaxHelper GetQuerySyntaxHelper() - { - return QuerySyntaxHelper; - } + public IQuerySyntaxHelper GetQuerySyntaxHelper() => QuerySyntaxHelper; /// /// Returns from the on the server. This is not not case sensitive. Requires @@ -158,15 +144,12 @@ public DiscoveredColumn DiscoverColumn(string specificColumnName,IManagedTransac { throw new ColumnMappingException(string.Format( FAnsiStrings.DiscoveredTable_DiscoverColumn_DiscoverColumn_failed__could_not_find_column_called___0___in_table___1__, specificColumnName, - _table), e); + TableName), e); } } /// - public string GetTopXSql(int topX) - { - return Helper.GetTopXSqlForTable(this, topX); - } + public string GetTopXSql(int topX) => Helper.GetTopXSqlForTable(this, topX); /// @@ -177,10 +160,7 @@ public string GetTopXSql(int topX) /// schema of the /// Optional - if set the connection to fetch the data will be sent on the connection on which the current is open /// - public DataTable GetDataTable(int topX = int.MaxValue,bool enforceTypesAndNullness = true, IManagedTransaction transaction = null) - { - return GetDataTable(new DatabaseOperationArgs {TransactionIfAny = transaction},topX,enforceTypesAndNullness); - } + public DataTable GetDataTable(int topX = int.MaxValue,bool enforceTypesAndNullness = true, IManagedTransaction transaction = null) => GetDataTable(new DatabaseOperationArgs {TransactionIfAny = transaction},topX,enforceTypesAndNullness); public DataTable GetDataTable(DatabaseOperationArgs args,int topX = int.MaxValue, bool enforceTypesAndNullness = true) { @@ -208,10 +188,7 @@ public virtual void Drop() Helper.DropTable(connection.Connection,this); } - public int GetRowCount(IManagedTransaction transaction = null) - { - return GetRowCount(new DatabaseOperationArgs { TransactionIfAny = transaction}); - } + public int GetRowCount(IManagedTransaction transaction = null) => GetRowCount(new DatabaseOperationArgs { TransactionIfAny = transaction}); /// /// Returns the estimated number of rows in the table. This may use a short cut e.g. consulting sys.partitions in Sql @@ -219,30 +196,21 @@ public int GetRowCount(IManagedTransaction transaction = null) /// /// Options for the operation e.g timeout, using existing connection etc /// - public int GetRowCount(DatabaseOperationArgs args) - { - return Helper.GetRowCount(args, this); - } + public int GetRowCount(DatabaseOperationArgs args) => Helper.GetRowCount(args, this); /// /// Returns true if there are no rows in the table /// /// Optional - if set the query will be sent on the connection on which the current is open /// - public bool IsEmpty(IManagedTransaction transaction = null) - { - return IsEmpty(new DatabaseOperationArgs {TransactionIfAny = transaction}); - } + public bool IsEmpty(IManagedTransaction transaction = null) => IsEmpty(new DatabaseOperationArgs {TransactionIfAny = transaction}); /// /// Returns true if there are no rows in the table /// /// /// - public bool IsEmpty(DatabaseOperationArgs args) - { - return Helper.IsEmpty(args,this); - } + public bool IsEmpty(DatabaseOperationArgs args) => Helper.IsEmpty(args,this); /// /// Creates and runs an ALTER TABLE SQL statement that adds a new column to the table @@ -301,10 +269,7 @@ public void DropColumn(DiscoveredColumn column) /// /// Optional - records inserted should form part of the supplied ongoing transaction /// - public IBulkCopy BeginBulkInsert(IManagedTransaction transaction = null) - { - return BeginBulkInsert(CultureInfo.CurrentCulture, transaction); - } + public IBulkCopy BeginBulkInsert(IManagedTransaction transaction = null) => BeginBulkInsert(CultureInfo.CurrentCulture, transaction); /// /// Creates a new object for bulk inserting records into the table. You should use a using block since is . @@ -360,10 +325,7 @@ public void MakeDistinct(DatabaseOperationArgs args) /// Optional, If provided the SQL generated will be adjusted to create the alternate table instead (which could include going cross server type e.g. MySql to Sql Server) /// When using this parameter the table must not exist yet, use destinationDiscoveredDatabase.ExpectTable("MyYetToExistTable") /// - public string ScriptTableCreation(bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable toCreateTable = null) - { - return Helper.ScriptTableCreation(this, dropPrimaryKeys, dropNullability, convertIdentityToInt, toCreateTable); - } + public string ScriptTableCreation(bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable toCreateTable = null) => Helper.ScriptTableCreation(this, dropPrimaryKeys, dropNullability, convertIdentityToInt, toCreateTable); /// /// Issues a database command to rename the table on the database server. @@ -373,7 +335,7 @@ public void Rename(string newName) { using var connection = Database.Server.GetManagedConnection(); Helper.RenameTable(this,newName,connection); - _table = newName; + TableName = newName; } /// @@ -423,10 +385,7 @@ public void CreatePrimaryKey(DatabaseOperationArgs args, params DiscoveredColumn /// /// /// - public int Insert(Dictionary toInsert, IManagedTransaction transaction = null) - { - return Insert(toInsert, null, transaction); - } + public int Insert(Dictionary toInsert, IManagedTransaction transaction = null) => Insert(toInsert, null, transaction); /// /// Inserts the values specified into the database table and returns the last autonum identity generated (or 0 if none present) @@ -462,10 +421,8 @@ public int Insert(Dictionary toInsert, CultureInfo cult /// /// ongoing transaction this insert should be part of /// - public int Insert(Dictionary toInsert, IManagedTransaction transaction = null) - { - return Insert(toInsert,null, transaction); - } + public int Insert(Dictionary toInsert, IManagedTransaction transaction = null) => Insert(toInsert,null, transaction); + /// /// Overload which will discover the columns by name for you. /// @@ -486,7 +443,7 @@ public int Insert(Dictionary toInsert, CultureInfo culture, IMan throw new ColumnMappingException(string.Format( FAnsiStrings .DiscoveredTable_Insert_Insert_failed__could_not_find_column_called___0___in_table___1__, k, - _table)); + TableName)); foundColumns.Add(match,toInsert[k]); } @@ -496,10 +453,7 @@ public int Insert(Dictionary toInsert, CultureInfo culture, IMan /// /// See /// - public DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) - { - return Database.Server.Helper.GetCommand(s, con, transaction); - } + public DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => Database.Server.Helper.GetCommand(s, con, transaction); /// /// Returns all foreign keys where this table is the parent table (i.e. the primary key table). @@ -522,16 +476,14 @@ public bool Equals(DiscoveredTable other) if (other is null) return false; return - string.Equals(_table, other._table, StringComparison.OrdinalIgnoreCase) + string.Equals(TableName, other.TableName, StringComparison.OrdinalIgnoreCase) && string.Equals(GetSchemaWithDefaultForNull(), other.GetSchemaWithDefaultForNull(), StringComparison.OrdinalIgnoreCase) && Equals(Database, other.Database) && TableType == other.TableType; } - private string GetSchemaWithDefaultForNull() - { + private string GetSchemaWithDefaultForNull() => //for "dbo, "" and null are all considered the same - return string.IsNullOrWhiteSpace(Schema) ? GetQuerySyntaxHelper().GetDefaultSchemaIfAny() : Schema; - } + string.IsNullOrWhiteSpace(Schema) ? GetQuerySyntaxHelper().GetDefaultSchemaIfAny() : Schema; /// /// Based on table name, schema, database and TableType @@ -562,10 +514,7 @@ public override int GetHashCode() } } - public DiscoveredRelationship AddForeignKey(DiscoveredColumn foreignKey, DiscoveredColumn primaryKey, bool cascadeDeletes,string constraintName = null, DatabaseOperationArgs args = null) - { - return AddForeignKey(new Dictionary{{foreignKey,primaryKey}},cascadeDeletes,constraintName,args); - } + public DiscoveredRelationship AddForeignKey(DiscoveredColumn foreignKey, DiscoveredColumn primaryKey, bool cascadeDeletes,string constraintName = null, DatabaseOperationArgs args = null) => AddForeignKey(new Dictionary{{foreignKey,primaryKey}},cascadeDeletes,constraintName,args); /// /// @@ -578,9 +527,6 @@ public DiscoveredRelationship AddForeignKey(DiscoveredColumn foreignKey, Discove /// Options for timeout, transaction etc /// public DiscoveredRelationship AddForeignKey(Dictionary foreignKeyPairs, - bool cascadeDeletes,string constraintName = null, DatabaseOperationArgs args = null) - { - return Helper.AddForeignKey(args??new DatabaseOperationArgs(),foreignKeyPairs, cascadeDeletes,constraintName); - } - + bool cascadeDeletes,string constraintName = null, DatabaseOperationArgs args = null) => + Helper.AddForeignKey(args??new DatabaseOperationArgs(),foreignKeyPairs, cascadeDeletes,constraintName); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/DiscoveredTableHelper.cs b/FAnsiSql/Discovery/DiscoveredTableHelper.cs index d806ba93..737ea0d5 100644 --- a/FAnsiSql/Discovery/DiscoveredTableHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredTableHelper.cs @@ -103,11 +103,9 @@ public string ScriptTableCreation(DiscoveredTable table, bool dropPrimaryKeys, b //if there is a collation if (!string.IsNullOrWhiteSpace(c.Collation) && (toCreateTable == null || !isToDifferentDatabaseType)) - { //if the script is to be run on a database of the same type //then specify that the column should use the live collation colRequest.Collation = c.Collation; - } columns.Add(colRequest); } @@ -119,10 +117,7 @@ public string ScriptTableCreation(DiscoveredTable table, bool dropPrimaryKeys, b return table.Database.Helper.GetCreateTableSql(destinationTable.Database, destinationTable.GetRuntimeName(), [.. columns], null, false, schema); } - public virtual bool IsEmpty(DatabaseOperationArgs args, DiscoveredTable discoveredTable) - { - return GetRowCount(args, discoveredTable) == 0; - } + public virtual bool IsEmpty(DatabaseOperationArgs args, DiscoveredTable discoveredTable) => GetRowCount(args, discoveredTable) == 0; public virtual void RenameTable(DiscoveredTable discoveredTable, string newName, IManagedConnection connection) { diff --git a/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs b/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs index fa9b7315..ecec8443 100644 --- a/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs +++ b/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs @@ -9,16 +9,18 @@ namespace FAnsi.Discovery; /// Cross database type reference to a Table valued function in a Database (actually currently only supported by Microsoft Sql Server). For views see /// DiscoveredTable /// -public sealed class DiscoveredTableValuedFunction(DiscoveredDatabase database, string functionName, - IQuerySyntaxHelper querySyntaxHelper, string schema = null) : DiscoveredTable(database, table: functionName, querySyntaxHelper, +public sealed class DiscoveredTableValuedFunction(DiscoveredDatabase database, + string functionName, + IQuerySyntaxHelper querySyntaxHelper, + string schema = null) : DiscoveredTable(database, functionName, querySyntaxHelper, schema, TableType.TableValuedFunction) { public override bool Exists(IManagedTransaction transaction = null) { - return Database.DiscoverTableValuedFunctions(transaction).Any(f=>f.GetRuntimeName().Equals(GetRuntimeName())); + return Database.DiscoverTableValuedFunctions(transaction).Any(f => f.GetRuntimeName().Equals(GetRuntimeName())); } - public override string GetRuntimeName() => QuerySyntaxHelper.GetRuntimeName(functionName); + public override string GetRuntimeName() => QuerySyntaxHelper.GetRuntimeName(TableName); public override string GetFullyQualifiedName() { @@ -29,7 +31,7 @@ public override string GetFullyQualifiedName() return $"{Database.GetRuntimeName()}..{GetRuntimeName()}({parameters})"; } - public override string ToString() => functionName; + public override string ToString() => TableName; public override void Drop() { diff --git a/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs b/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs index 1e99079e..037be026 100644 --- a/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs +++ b/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs @@ -24,10 +24,7 @@ public sealed class CustomLine(string text, QueryComponent locationToInsert) /// public string StackTrace { get; private set; } = Environment.StackTrace; - public override string ToString() - { - return Text; - } + public override string ToString() => Text; /// /// Returns the section of which does not include any alias e.g. returns "UPPER('a')" from "UPPER('a') as a" diff --git a/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs b/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs index 77370afd..fde4e7ce 100644 --- a/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs +++ b/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs @@ -7,8 +7,5 @@ namespace FAnsi.Discovery.QuerySyntax; /// public sealed class QuerySyntaxHelperFactory { - public static IQuerySyntaxHelper Create(DatabaseType type) - { - return ImplementationManager.GetImplementation(type).GetQuerySyntaxHelper(); - } + public static IQuerySyntaxHelper Create(DatabaseType type) => ImplementationManager.GetImplementation(type).GetQuerySyntaxHelper(); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/QuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntaxHelper.cs index f491f717..6aa4ad68 100644 --- a/FAnsiSql/Discovery/QuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntaxHelper.cs @@ -70,24 +70,16 @@ public abstract partial class QuerySyntaxHelper( /// " AS " qualifier is used explicitly. The capture groups of this Regex must match /// /// - protected Regex GetAliasRegex() - { + protected Regex GetAliasRegex() => //whitespace followed by as and more whitespace //Then any word (optionally bounded by a table name qualifier) - //alias is a word //(w+) - //alias is a wrapped word e.g. [hey hey]. In this case we must allow anything between the brackets that is not closing bracket //[[`""]([^[`""]+)[]`""] + AliasRegex(); - return AliasRegex(); - } - - private static string GetAliasConst() - { - return " AS "; - } + private static string GetAliasConst() => " AS "; public string AliasPrefix => GetAliasConst(); @@ -116,10 +108,7 @@ public static string GetParameterNameFromDeclarationSQL(string parameterSQL) return ParameterNamesRegex.Match(parameterSQL).Value.Trim(); } - public bool IsValidParameterName(string parameterSQL) - { - return ParameterNamesRegex.IsMatch(parameterSQL); - } + public bool IsValidParameterName(string parameterSQL) => ParameterNamesRegex.IsMatch(parameterSQL); public virtual string GetRuntimeName(string s) @@ -158,10 +147,7 @@ public virtual string GetRuntimeName(string s) /// /// A wrapped name after it has had the opening and closing qualifiers stripped off e.g. "Fi``sh" /// The final runtime name unescaped e.g. "Fi`sh" - protected virtual string UnescapeWrappedNameBody(string name) - { - return name; - } + protected virtual string UnescapeWrappedNameBody(string name) => name; public virtual bool TryGetRuntimeName(string s,out string name) { @@ -205,15 +191,9 @@ public virtual string EnsureFullyQualified(string databaseName, string schema, s public virtual string Escape(string sql) => string.IsNullOrWhiteSpace(sql) ? sql : sql.Replace("'", "''"); public abstract TopXResponse HowDoWeAchieveTopX(int x); - public virtual string GetParameterDeclaration(string proposedNewParameterName, DatabaseTypeRequest request) - { - return GetParameterDeclaration(proposedNewParameterName, TypeTranslater.GetSQLDBTypeForCSharpType(request)); - } + public virtual string GetParameterDeclaration(string proposedNewParameterName, DatabaseTypeRequest request) => GetParameterDeclaration(proposedNewParameterName, TypeTranslater.GetSQLDBTypeForCSharpType(request)); - public virtual HashSet GetReservedWords() - { - return new HashSet(StringComparer.CurrentCultureIgnoreCase); - } + public virtual HashSet GetReservedWords() => new(StringComparer.CurrentCultureIgnoreCase); public abstract string GetParameterDeclaration(string proposedNewParameterName, string sqlType); @@ -300,12 +280,10 @@ public static string MakeHeaderNameSensible(string header) //Camel case after spaces for (var i = 0; i < sb.Length; i++) - { //if we are looking at a space if (sb[i] == ' ' && i + 1 < sb.Length && sb[i + 1] >= 'a' && sb[i + 1] <= 'z') //and there is another character //and that character is a lower case letter sb[i + 1] = char.ToUpper(sb[i + 1]); - } adjustedHeader = sb.ToString().Replace(" ", ""); @@ -342,18 +320,14 @@ public bool IsBasicallyNull(object value) return value == null || value == DBNull.Value; } - public virtual bool IsTimeout(Exception exception) - { - + public virtual bool IsTimeout(Exception exception) => /* //todo doesn't work with .net standard var oleE = exception as OleDbException; if (oleE != null && oleE.ErrorCode == -2147217871) return true;*/ - - return exception.Message.Contains("timeout", StringComparison.OrdinalIgnoreCase); - } + exception.Message.Contains("timeout", StringComparison.OrdinalIgnoreCase); public abstract string HowDoWeAchieveMd5(string selectSql); @@ -380,16 +354,10 @@ public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn var decider = factories[culture].Create(cSharpType); var o = decider.Parse(strVal); - if(o is DateTime d) - { - o = FormatDateTimeForDbParameter(d); - } + if(o is DateTime d) o = FormatDateTimeForDbParameter(d); //Not all DBMS support DBParameter.Value = new TimeSpan(...); - if (o is TimeSpan t) - { - o = FormatTimespanForDbParameter(t); - } + if (o is TimeSpan t) o = FormatTimespanForDbParameter(t); p.Value = o; @@ -440,10 +408,7 @@ public bool IsValidColumnName(string columnName,out string reason) return string.IsNullOrWhiteSpace(reason); } - public virtual string GetDefaultSchemaIfAny() - { - return null; - } + public virtual string GetDefaultSchemaIfAny() => null; /// /// returns null if the name is valid. Otherwise a string describing why it is invalid. @@ -471,10 +436,7 @@ private string ValidateName(string candidate, string objectType, int maximumLeng - public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn, object value) - { - return GetParameter(p,discoveredColumn,value,null); - } + public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn, object value) => GetParameter(p,discoveredColumn,value,null); /// /// @@ -485,10 +447,7 @@ public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn /// /// /// - protected virtual object FormatDateTimeForDbParameter(DateTime dateTime) - { - return dateTime; - } + protected virtual object FormatDateTimeForDbParameter(DateTime dateTime) => dateTime; /// /// Return the appropriate value such that it can be put into a DbParameter.Value field and be succesfully inserted into a @@ -496,10 +455,7 @@ protected virtual object FormatDateTimeForDbParameter(DateTime dateTime) /// /// /// - protected virtual object FormatTimespanForDbParameter(TimeSpan timeSpan) - { - return timeSpan; - } + protected virtual object FormatTimespanForDbParameter(TimeSpan timeSpan) => timeSpan; #region Equality Members protected bool Equals(QuerySyntaxHelper other) @@ -519,10 +475,8 @@ public override bool Equals(object obj) return Equals((QuerySyntaxHelper)obj); } - public override int GetHashCode() - { - return GetType().GetHashCode(); - } + public override int GetHashCode() => GetType().GetHashCode(); + #endregion public Dictionary GetParameterNamesFor(T[] columns, Func toStringFunc) diff --git a/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs b/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs index c1973824..2f5fe7b8 100644 --- a/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs +++ b/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs @@ -91,15 +91,9 @@ public string GetSQLDBTypeForCSharpType(DatabaseTypeRequest request) throw new TypeNotMappedException(string.Format(FAnsiStrings.TypeTranslater_GetSQLDBTypeForCSharpType_Unsure_what_SQL_type_to_use_for_CSharp_Type___0_____TypeTranslater_was___1__, t.Name, GetType().Name)); } - private static string GetByteArrayDataType() - { - return "varbinary(max)"; - } + private static string GetByteArrayDataType() => "varbinary(max)"; - private static string GetByteDataType() - { - return "tinyint"; - } + private static string GetByteDataType() => "tinyint"; private static string GetFloatingPointDataType(DecimalSize decimalSize) { @@ -109,10 +103,7 @@ private static string GetFloatingPointDataType(DecimalSize decimalSize) return $"decimal({decimalSize.Precision},{decimalSize.Scale})"; } - protected virtual string GetDateDateTimeDataType() - { - return "datetime"; - } + protected virtual string GetDateDateTimeDataType() => "datetime"; protected string GetStringDataType(int? maxExpectedStringWidth) { @@ -125,10 +116,7 @@ protected string GetStringDataType(int? maxExpectedStringWidth) return GetStringDataTypeImpl(maxExpectedStringWidth.Value); } - protected virtual string GetStringDataTypeImpl(int maxExpectedStringWidth) - { - return $"varchar({maxExpectedStringWidth})"; - } + protected virtual string GetStringDataTypeImpl(int maxExpectedStringWidth) => $"varchar({maxExpectedStringWidth})"; public abstract string GetStringDataTypeWithUnlimitedWidth(); @@ -144,55 +132,32 @@ private string GetUnicodeStringDataType(int? maxExpectedStringWidth) return GetUnicodeStringDataTypeImpl(maxExpectedStringWidth.Value); } - protected virtual string GetUnicodeStringDataTypeImpl(int maxExpectedStringWidth) - { - return $"nvarchar({maxExpectedStringWidth})"; - } + protected virtual string GetUnicodeStringDataTypeImpl(int maxExpectedStringWidth) => $"nvarchar({maxExpectedStringWidth})"; public abstract string GetUnicodeStringDataTypeWithUnlimitedWidth(); - protected virtual string GetTimeDataType() - { - return "time"; - } + protected virtual string GetTimeDataType() => "time"; - protected virtual string GetBoolDataType() - { - return "bit"; - } + protected virtual string GetBoolDataType() => "bit"; - protected virtual string GetSmallIntDataType() - { - return "smallint"; - } + protected virtual string GetSmallIntDataType() => "smallint"; - protected virtual string GetIntDataType() - { - return "int"; - } + protected virtual string GetIntDataType() => "int"; - protected virtual string GetBigIntDataType() - { - return "bigint"; - } + protected virtual string GetBigIntDataType() => "bigint"; - private static string GetGuidDataType() - { - return "uniqueidentifier"; - } + private static string GetGuidDataType() => "uniqueidentifier"; /// [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] - public Type GetCSharpTypeForSQLDBType(string sqlType) - { - return TryGetCSharpTypeForSQLDBType(sqlType) ?? - throw new TypeNotMappedException(string.Format( - FAnsiStrings - .TypeTranslater_GetCSharpTypeForSQLDBType_No_CSharp_type_mapping_exists_for_SQL_type___0____TypeTranslater_was___1___, - sqlType, GetType().Name)); - } + public Type GetCSharpTypeForSQLDBType(string sqlType) => + TryGetCSharpTypeForSQLDBType(sqlType) ?? + throw new TypeNotMappedException(string.Format( + FAnsiStrings + .TypeTranslater_GetCSharpTypeForSQLDBType_No_CSharp_type_mapping_exists_for_SQL_type___0____TypeTranslater_was___1___, + sqlType, GetType().Name)); /// [return: @@ -237,10 +202,7 @@ public Type TryGetCSharpTypeForSQLDBType(string sqlType) } /// - public bool IsSupportedSQLDBType(string sqlType) - { - return TryGetCSharpTypeForSQLDBType(sqlType) != null; - } + public bool IsSupportedSQLDBType(string sqlType) => TryGetCSharpTypeForSQLDBType(sqlType) != null; /// public DbType GetDbTypeForSQLDBType(string sqlType) @@ -317,15 +279,9 @@ public virtual DatabaseTypeRequest GetDataTypeRequestForSQLDBType(string sqlType /// /// /// - private static bool IsUnicode(string sqlType) - { - return sqlType != null && sqlType.StartsWith("n",StringComparison.CurrentCultureIgnoreCase); - } + private static bool IsUnicode(string sqlType) => sqlType != null && sqlType.StartsWith("n",StringComparison.CurrentCultureIgnoreCase); - public virtual Guesser GetGuesserFor(DiscoveredColumn discoveredColumn) - { - return GetGuesserFor(discoveredColumn, 0); - } + public virtual Guesser GetGuesserFor(DiscoveredColumn discoveredColumn) => GetGuesserFor(discoveredColumn, 0); protected Guesser GetGuesserFor(DiscoveredColumn discoveredColumn, int extraLengthPerNonAsciiCharacter) { @@ -384,8 +340,7 @@ public string TranslateSQLDBType(string sqlType, ITypeTranslater destinationType /// currently loaded data. /// /// - private static int GetStringLengthForTimeSpan() - { + private static int GetStringLengthForTimeSpan() => /* * * To determine this you can run the following SQL: @@ -405,8 +360,7 @@ select LEN(dt) from omgTimes * * */ - return 16; //e.g. "13:10:58.2300000" - } + 16; //e.g. "13:10:58.2300000" /// /// Return the number of characters required to not truncate/loose any data when altering a column from datetime (e.g. datetime2, DATE etc) to varchar(x). Return @@ -415,8 +369,7 @@ select LEN(dt) from omgTimes /// currently loaded data. /// /// - private static int GetStringLengthForDateTime() - { + private static int GetStringLengthForDateTime() => /* To determine this you can run the following SQL: @@ -432,55 +385,29 @@ alter table omgdates alter column dt varchar(100) select LEN(dt) from omgdates */ + Guesser.MinimumLengthRequiredForDateStringRepresentation; //e.g. "2018-01-30 13:05:45.1266667" - return Guesser.MinimumLengthRequiredForDateStringRepresentation; //e.g. "2018-01-30 13:05:45.1266667" - } + protected virtual bool IsBit(string sqlType) => BitRegex.IsMatch(sqlType); - protected virtual bool IsBit(string sqlType) - { - return BitRegex.IsMatch(sqlType); - } - protected bool IsByte(string sqlType) - { - return ByteRegex.IsMatch(sqlType); - } - protected virtual bool IsSmallInt(string sqlType) - { - return SmallIntRegex.IsMatch(sqlType); - } - protected virtual bool IsInt(string sqlType) - { - return IntRegex.IsMatch(sqlType); - } - protected virtual bool IsLong(string sqlType) - { - return LongRegex.IsMatch(sqlType); - } - protected bool IsDate(string sqlType) - { - return DateRegex.IsMatch(sqlType); - } - protected bool IsTime(string sqlType) - { - return TimeRegex.IsMatch(sqlType); - } - protected virtual bool IsString(string sqlType) - { - return StringRegex.IsMatch(sqlType); - } - protected virtual bool IsByteArray(string sqlType) - { - return ByteArrayRegex.IsMatch(sqlType); - } - protected virtual bool IsFloatingPoint(string sqlType) - { - return FloatingPointRegex.IsMatch(sqlType); - } + protected bool IsByte(string sqlType) => ByteRegex.IsMatch(sqlType); - private static bool IsGuid(string sqlType) - { - return GuidRegex.IsMatch(sqlType); - } + protected virtual bool IsSmallInt(string sqlType) => SmallIntRegex.IsMatch(sqlType); + + protected virtual bool IsInt(string sqlType) => IntRegex.IsMatch(sqlType); + + protected virtual bool IsLong(string sqlType) => LongRegex.IsMatch(sqlType); + + protected bool IsDate(string sqlType) => DateRegex.IsMatch(sqlType); + + protected bool IsTime(string sqlType) => TimeRegex.IsMatch(sqlType); + + protected virtual bool IsString(string sqlType) => StringRegex.IsMatch(sqlType); + + protected virtual bool IsByteArray(string sqlType) => ByteArrayRegex.IsMatch(sqlType); + + protected virtual bool IsFloatingPoint(string sqlType) => FloatingPointRegex.IsMatch(sqlType); + + private static bool IsGuid(string sqlType) => GuidRegex.IsMatch(sqlType); [GeneratedRegex(StringSizeRegexPattern)] private static partial Regex StringSizeRegex(); diff --git a/FAnsiSql/Extensions/DataColumnExtensions.cs b/FAnsiSql/Extensions/DataColumnExtensions.cs index 002ef8ad..5f49b505 100644 --- a/FAnsiSql/Extensions/DataColumnExtensions.cs +++ b/FAnsiSql/Extensions/DataColumnExtensions.cs @@ -33,11 +33,7 @@ public static void SetDoNotReType(this DataColumn dc, bool value) /// /// /// - public static bool GetDoNotReType(this DataColumn dc) - { - return - dc.DataType == typeof(string) && - dc.ExtendedProperties[DoNotReTypeExtendedProperty] is true; - } - + public static bool GetDoNotReType(this DataColumn dc) => + dc.DataType == typeof(string) && + dc.ExtendedProperties[DoNotReTypeExtendedProperty] is true; } \ No newline at end of file diff --git a/FAnsiSql/FAnsi.csproj b/FAnsiSql/FAnsi.csproj index 81309e7a..8c21f070 100644 --- a/FAnsiSql/FAnsi.csproj +++ b/FAnsiSql/FAnsi.csproj @@ -16,19 +16,16 @@ Health Informatics Centre, University of Dundee HIC.FAnsiSql FAnsiSql is a database management/ETL library that allows you to perform common SQL operations without having to know which Database Management System (DBMS) you are targetting (e.g. Sql Server, My Sql, Oracle). - Copyright © 2019-2023 + Copyright © 2019-2024 false true true CS1591 en-GB + embedded 1 - embedded - - - embedded diff --git a/FAnsiSql/Implementation/ImplementationManager.cs b/FAnsiSql/Implementation/ImplementationManager.cs index b610c5b3..2df7a1d7 100644 --- a/FAnsiSql/Implementation/ImplementationManager.cs +++ b/FAnsiSql/Implementation/ImplementationManager.cs @@ -62,19 +62,13 @@ public static IImplementation GetImplementation(DbConnection connection) .ImplementationManager_GetImplementation_No_implementation_found_for_ADO_Net_object_of_Type__0_, connection.GetType())); } - private static IImplementation GetImplementation(Func condition, string errorIfNotFound) - { - return Instance?._implementations.FirstOrDefault(condition)??throw new ImplementationNotFoundException(errorIfNotFound); - } + private static IImplementation GetImplementation(Func condition, string errorIfNotFound) => Instance?._implementations.FirstOrDefault(condition)??throw new ImplementationNotFoundException(errorIfNotFound); /// /// Returns all currently loaded implementations or null if no implementations have been loaded /// /// - public static ReadOnlyCollection GetImplementations() - { - return Instance._implementations.AsReadOnly(); - } + public static ReadOnlyCollection GetImplementations() => Instance._implementations.AsReadOnly(); /// /// Clears all currently loaded diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs index 05ad5ae6..797fc7ac 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs @@ -28,15 +28,9 @@ private MicrosoftQuerySyntaxHelper() : base(MicrosoftSQLTypeTranslater.Instance, public override string CloseQualifier => "]"; - public override TopXResponse HowDoWeAchieveTopX(int x) - { - return new TopXResponse($"TOP {x}", QueryComponent.SELECT); - } + public override TopXResponse HowDoWeAchieveTopX(int x) => new($"TOP {x}", QueryComponent.SELECT); - public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) - { - return $"DECLARE {proposedNewParameterName} AS {sqlType};"; - } + public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) => $"DECLARE {proposedNewParameterName} AS {sqlType};"; public override string GetScalarFunctionSql(MandatoryScalarFunctions function) => function switch @@ -47,10 +41,7 @@ public override string GetScalarFunctionSql(MandatoryScalarFunctions function) = _ => throw new ArgumentOutOfRangeException(nameof(function)) }; - public override string GetAutoIncrementKeywordIfAny() - { - return "IDENTITY(1,1)"; - } + public override string GetAutoIncrementKeywordIfAny() => "IDENTITY(1,1)"; public override Dictionary GetSQLFunctionsDictionary() => new() @@ -80,41 +71,23 @@ 3617 when string.IsNullOrWhiteSpace(sqlE.Message) => true, }; } - public override string HowDoWeAchieveMd5(string selectSql) - { - return $"CONVERT(NVARCHAR(32),HASHBYTES('MD5', CONVERT(varbinary,{selectSql})),2)"; - } + public override string HowDoWeAchieveMd5(string selectSql) => $"CONVERT(NVARCHAR(32),HASHBYTES('MD5', CONVERT(varbinary,{selectSql})),2)"; - public override string GetDefaultSchemaIfAny() - { - return "dbo"; - } + public override string GetDefaultSchemaIfAny() => "dbo"; - public override bool SupportsEmbeddedParameters() - { - return true; - } + public override bool SupportsEmbeddedParameters() => true; - public override string EnsureWrappedImpl(string databaseOrTableName) - { - return $"[{GetRuntimeNameWithDoubledClosingSquareBrackets(databaseOrTableName)}]"; - } + public override string EnsureWrappedImpl(string databaseOrTableName) => $"[{GetRuntimeNameWithDoubledClosingSquareBrackets(databaseOrTableName)}]"; - protected override string UnescapeWrappedNameBody(string name) - { - return name.Replace("]]","]"); - } + protected override string UnescapeWrappedNameBody(string name) => name.Replace("]]","]"); /// /// Returns the runtime name of the string with all ending square brackets escaped by doubling up (but resulting string is not wrapped itself) /// /// /// - private string GetRuntimeNameWithDoubledClosingSquareBrackets(string s) - { - return GetRuntimeName(s)?.Replace("]","]]"); - } + private string GetRuntimeNameWithDoubledClosingSquareBrackets(string s) => GetRuntimeName(s)?.Replace("]","]]"); public override string EnsureFullyQualified(string databaseName, string schema, string tableName) { diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs index 6453aef3..f6a9ff58 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs @@ -215,9 +215,7 @@ private static void EmptyStringsToNulls(DataTable dt) .Select(row => new { row, o = row[col] }) .Where(static t => t.o != DBNull.Value && t.o != null && string.IsNullOrWhiteSpace(t.o.ToString())) .Select(static t => t.row)) - { row[col] = DBNull.Value; - } } [Pure] diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs index 7e3d1986..d47ca2c0 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs @@ -17,7 +17,7 @@ public sealed class MicrosoftSQLDatabaseHelper: DiscoveredDatabaseHelper /// Defaults to true. This command makes dropping databases more robust so is recommended but /// is not supported by some servers (e.g. Microsoft Azure) /// - public static bool SetSingleUserWhenDroppingDatabases = true; + public static bool SetSingleUserWhenDroppingDatabases { get; set; } = true; public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction transaction = null) { @@ -100,10 +100,7 @@ public override DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStr return [.. toReturn]; } - public override IDiscoveredTableHelper GetTableHelper() - { - return new MicrosoftSQLTableHelper(); - } + public override IDiscoveredTableHelper GetTableHelper() => new MicrosoftSQLTableHelper(); public override void DropDatabase(DiscoveredDatabase database) { diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs index 61ba5877..4981093b 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs @@ -23,35 +23,17 @@ private MicrosoftSQLServerHelper() : base(DatabaseType.MicrosoftSQLServer) protected override string ConnectionTimeoutKeyName => "Connect Timeout"; #region Up Typing - public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) - { - return new SqlCommand(s, (SqlConnection)con, transaction as SqlTransaction); - } + public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => new SqlCommand(s, (SqlConnection)con, transaction as SqlTransaction); - public override DbDataAdapter GetDataAdapter(DbCommand cmd) - { - return new SqlDataAdapter((SqlCommand) cmd); - } + public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new SqlDataAdapter((SqlCommand) cmd); - public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) - { - return new SqlCommandBuilder((SqlDataAdapter) GetDataAdapter(cmd)); - } + public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) => new SqlCommandBuilder((SqlDataAdapter) GetDataAdapter(cmd)); - public override DbParameter GetParameter(string parameterName) - { - return new SqlParameter(parameterName,null); - } + public override DbParameter GetParameter(string parameterName) => new SqlParameter(parameterName,null); - public override DbConnection GetConnection(DbConnectionStringBuilder builder) - { - return new SqlConnection(builder.ConnectionString); - } + public override DbConnection GetConnection(DbConnectionStringBuilder builder) => new SqlConnection(builder.ConnectionString); - protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString) - { - return new SqlConnectionStringBuilder(connectionString); - } + protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString) => new SqlConnectionStringBuilder(connectionString); protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string server, string database, string username, string password) { @@ -69,10 +51,8 @@ protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(stri return toReturn; } - public static string GetDatabaseNameFrom(DbConnectionStringBuilder builder) - { - return ((SqlConnectionStringBuilder) builder).InitialCatalog; - } + public static string GetDatabaseNameFrom(DbConnectionStringBuilder builder) => ((SqlConnectionStringBuilder) builder).InitialCatalog; + #endregion @@ -112,15 +92,9 @@ public override DbConnectionStringBuilder EnableAsync(DbConnectionStringBuilder return b; } - public override IDiscoveredDatabaseHelper GetDatabaseHelper() - { - return new MicrosoftSQLDatabaseHelper(); - } + public override IDiscoveredDatabaseHelper GetDatabaseHelper() => new MicrosoftSQLDatabaseHelper(); - public override IQuerySyntaxHelper GetQuerySyntaxHelper() - { - return MicrosoftQuerySyntaxHelper.Instance; - } + public override IQuerySyntaxHelper GetQuerySyntaxHelper() => MicrosoftQuerySyntaxHelper.Instance; public override void CreateDatabase(DbConnectionStringBuilder builder, IHasRuntimeName newDatabaseName) { @@ -188,10 +162,7 @@ protected override void EnforceKeywords(DbConnectionStringBuilder builder) // if user has specified a keyword that indicates Azure authentication // then disable IntegratedSecurity - if (msb.Authentication != SqlAuthenticationMethod.NotSpecified) - { - msb.IntegratedSecurity = false; - } + if (msb.Authentication != SqlAuthenticationMethod.NotSpecified) msb.IntegratedSecurity = false; } public override Version GetVersion(DiscoveredServer server) diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs index 3382c678..3b508fa5 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs @@ -76,10 +76,7 @@ private static string GetObjectName(DiscoveredTable table) return table.Schema != null ? $"{syntax.EnsureWrapped(table.Schema)}.{objectName}" : objectName; } - public override IDiscoveredColumnHelper GetColumnHelper() - { - return new MicrosoftSQLColumnHelper(); - } + public override IDiscoveredColumnHelper GetColumnHelper() => new MicrosoftSQLColumnHelper(); public override void DropTable(DbConnection connection, DiscoveredTable tableToDrop) { @@ -165,10 +162,7 @@ sys.parameters.precision AS PRECISION return toReturn.ToArray(); } - public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable,IManagedConnection connection,CultureInfo culture) - { - return new MicrosoftSQLBulkCopy(discoveredTable,connection,culture); - } + public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable,IManagedConnection connection,CultureInfo culture) => new MicrosoftSQLBulkCopy(discoveredTable,connection,culture); public override void CreatePrimaryKey(DatabaseOperationArgs args, DiscoveredTable table, DiscoveredColumn[] discoverColumns) { @@ -312,10 +306,7 @@ where RowNum > 1 } - public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) - { - return $"SELECT TOP {topX} * FROM {table.GetFullyQualifiedName()}"; - } + public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) => $"SELECT TOP {topX} * FROM {table.GetFullyQualifiedName()}"; private string GetSQLType_FromSpColumnsResult(DbDataReader r) { @@ -325,10 +316,7 @@ private string GetSQLType_FromSpColumnsResult(DbDataReader r) if (HasPrecisionAndScale(columnType)) lengthQualifier = $"({r["PRECISION"]},{r["SCALE"]})"; else - if (RequiresLength(columnType)) - { - lengthQualifier = $"({AdjustForUnicodeAndNegativeOne(columnType, Convert.ToInt32(r["LENGTH"]))})"; - } + if (RequiresLength(columnType)) lengthQualifier = $"({AdjustForUnicodeAndNegativeOne(columnType, Convert.ToInt32(r["LENGTH"]))})"; if (columnType == "text") return "varchar(max)"; diff --git a/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs b/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs index bd2b95ee..c1aa27a0 100644 --- a/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs @@ -52,10 +52,7 @@ protected override string GetCreateTableSqlLineForColumn(DatabaseColumnRequest c $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} CHARACTER SET utf8mb4 {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} COLLATE {col.Collation ?? "utf8mb4_bin"} {(col.AllowNulls && !col.IsPrimaryKey ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; } - public override DirectoryInfo Detach(DiscoveredDatabase database) - { - throw new NotImplementedException(); - } + public override DirectoryInfo Detach(DiscoveredDatabase database) => throw new NotImplementedException(); public override void CreateBackup(DiscoveredDatabase discoveredDatabase, string backupName) { diff --git a/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs b/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs index 8179d680..14c3a0fb 100644 --- a/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs @@ -49,18 +49,15 @@ public override string EnsureFullyQualified(string databaseName, string schema, public override TopXResponse HowDoWeAchieveTopX(int x) => new($"LIMIT {x}",QueryComponent.Postfix); - public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) - { + public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) => //MySql doesn't require parameter declaration you just start using it like javascript - return $"/* {proposedNewParameterName} */"; - } + $"/* {proposedNewParameterName} */"; public override string Escape(string sql) { // https://dev.mysql.com/doc/refman/8.0/en/string-literals.html var r = new StringBuilder(sql.Length); foreach (var c in sql) - { r.Append(c switch { '\0' => "\\0", @@ -72,12 +69,11 @@ public override string Escape(string sql) '\t' => "\\t", '\u001a' => "\\Z", '\\' => "\\", -// Pattern matching only: -// '%' => "\\%", -// '_' => "\\_", + // Pattern matching only: + // '%' => "\\%", + // '_' => "\\_", _ => $"{c}" }); - } return r.ToString(); } @@ -94,10 +90,7 @@ public override string GetScalarFunctionSql(MandatoryScalarFunctions function) = public override string GetAutoIncrementKeywordIfAny() => "AUTO_INCREMENT"; - public override Dictionary GetSQLFunctionsDictionary() - { - return Functions; - } + public override Dictionary GetSQLFunctionsDictionary() => Functions; private static readonly Dictionary Functions = new() { diff --git a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs index cd27a3cd..bb4c6f1c 100644 --- a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs @@ -124,15 +124,10 @@ public override void DropColumn(DbConnection connection, DiscoveredColumn column public override IEnumerable DiscoverTableValuedFunctionParameters(DbConnection connection, - DiscoveredTableValuedFunction discoveredTableValuedFunction, DbTransaction transaction) - { + DiscoveredTableValuedFunction discoveredTableValuedFunction, DbTransaction transaction) => throw new NotImplementedException(); - } - public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable,IManagedConnection connection,CultureInfo culture) - { - return new MySqlBulkCopy(discoveredTable, connection,culture); - } + public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable,IManagedConnection connection,CultureInfo culture) => new MySqlBulkCopy(discoveredTable, connection,culture); public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table, DbConnection connection,IManagedTransaction transaction = null) { @@ -222,10 +217,7 @@ protected override string GetRenameTableSql(DiscoveredTable discoveredTable, str return $"RENAME TABLE {discoveredTable.GetWrappedName()} TO {syntax.EnsureWrapped(newName)};"; } - public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) - { - return $"SELECT * FROM {table.GetFullyQualifiedName()} LIMIT {topX}"; - } + public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) => $"SELECT * FROM {table.GetFullyQualifiedName()} LIMIT {topX}"; public override void DropFunction(DbConnection connection, DiscoveredTableValuedFunction functionToDrop) diff --git a/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs b/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs index eb80e32f..a2543e60 100644 --- a/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs +++ b/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs @@ -34,26 +34,15 @@ public override int GetLengthIfString(string sqlType) => _ => AlsoStringRegex.IsMatch(sqlType) ? int.MaxValue : base.GetLengthIfString(sqlType) }; - public override string GetStringDataTypeWithUnlimitedWidth() - { - return "longtext"; - } + public override string GetStringDataTypeWithUnlimitedWidth() => "longtext"; - public override string GetUnicodeStringDataTypeWithUnlimitedWidth() - { - return "longtext"; - } + public override string GetUnicodeStringDataTypeWithUnlimitedWidth() => "longtext"; - protected override string GetUnicodeStringDataTypeImpl(int maxExpectedStringWidth) - { - return $"varchar({maxExpectedStringWidth})"; - } + protected override string GetUnicodeStringDataTypeImpl(int maxExpectedStringWidth) => $"varchar({maxExpectedStringWidth})"; - protected override bool IsInt(string sqlType) - { + protected override bool IsInt(string sqlType) => //not an int - return !sqlType.StartsWith("int8", StringComparison.InvariantCultureIgnoreCase) && base.IsInt(sqlType); - } + !sqlType.StartsWith("int8", StringComparison.InvariantCultureIgnoreCase) && base.IsInt(sqlType); protected override bool IsString(string sqlType) { @@ -63,15 +52,9 @@ protected override bool IsString(string sqlType) return base.IsString(sqlType) || AlsoStringRegex.IsMatch(sqlType); } - protected override bool IsFloatingPoint(string sqlType) - { - return base.IsFloatingPoint(sqlType) || AlsoFloatingPoint.IsMatch(sqlType); - } + protected override bool IsFloatingPoint(string sqlType) => base.IsFloatingPoint(sqlType) || AlsoFloatingPoint.IsMatch(sqlType); - protected override bool IsBit(string sqlType) - { - return base.IsBit(sqlType) || AlsoBitRegex.IsMatch(sqlType); - } + protected override bool IsBit(string sqlType) => base.IsBit(sqlType) || AlsoBitRegex.IsMatch(sqlType); [GeneratedRegex(@"tinyint\(1\)", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] private static partial Regex AlsoBitRe(); diff --git a/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs b/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs index 98af0a23..46b95021 100644 --- a/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs +++ b/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs @@ -139,13 +139,7 @@ ORDER BY } - protected override string BuildPivotOnlyAggregate(AggregateCustomLineCollection query, CustomLine nonPivotColumn) - { - throw new NotImplementedException(); - } + protected override string BuildPivotOnlyAggregate(AggregateCustomLineCollection query, CustomLine nonPivotColumn) => throw new NotImplementedException(); - protected override string BuildPivotAndAxisAggregate(AggregateCustomLineCollection query) - { - throw new NotImplementedException(); - } + protected override string BuildPivotAndAxisAggregate(AggregateCustomLineCollection query) => throw new NotImplementedException(); } \ No newline at end of file diff --git a/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs b/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs index 082df042..3c5f1b06 100644 --- a/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs +++ b/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs @@ -60,25 +60,23 @@ public override int UploadImpl(DataTable dt) var values = mapping.Keys.ToDictionary(static c => c, static _ => new List()); foreach (DataRow dataRow in dt.Rows) - { //populate parameters for current row - foreach (var col in mapping.Keys) - { - var val = dataRow[col]; - - if (val is string stringVal && string.IsNullOrWhiteSpace(stringVal)) - val = null; - else - if (val == DBNull.Value) - val = null; - else if (dateColumns.Contains(col)) - val = val is string s ? (DateTime)DateTimeDecider.Parse(s) : Convert.ToDateTime(dataRow[col]); - - if (col.DataType == typeof(bool) && val is bool b) - values[col].Add(b?1:0); - else - values[col].Add(val); - } + foreach (var col in mapping.Keys) + { + var val = dataRow[col]; + + if (val is string stringVal && string.IsNullOrWhiteSpace(stringVal)) + val = null; + else + if (val == DBNull.Value) + val = null; + else if (dateColumns.Contains(col)) + val = val is string s ? (DateTime)DateTimeDecider.Parse(s) : Convert.ToDateTime(dataRow[col]); + + if (col.DataType == typeof(bool) && val is bool b) + values[col].Add(b?1:0); + else + values[col].Add(val); } foreach (var col in mapping.Keys) diff --git a/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs b/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs index e7e21940..6e89ba96 100644 --- a/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs @@ -24,10 +24,7 @@ public override void DropDatabase(DiscoveredDatabase database) cmd.ExecuteNonQuery(); } - public override Dictionary DescribeDatabase(DbConnectionStringBuilder builder, string database) - { - throw new NotImplementedException(); - } + public override Dictionary DescribeDatabase(DbConnectionStringBuilder builder, string database) => throw new NotImplementedException(); protected override string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) { @@ -39,10 +36,7 @@ protected override string GetCreateTableSqlLineForColumn(DatabaseColumnRequest c return base.GetCreateTableSqlLineForColumn(col, datatype, syntaxHelper); } - public override DirectoryInfo Detach(DiscoveredDatabase database) - { - throw new NotImplementedException(); - } + public override DirectoryInfo Detach(DiscoveredDatabase database) => throw new NotImplementedException(); public override void CreateBackup(DiscoveredDatabase discoveredDatabase, string backupName) { @@ -83,31 +77,19 @@ public override IEnumerable ListTables(DiscoveredDatabase paren } public override IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, - DbConnection connection, string database, DbTransaction transaction = null) - { - return Array.Empty(); - } + DbConnection connection, string database, DbTransaction transaction = null) => + Array.Empty(); - public override DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStringBuilder builder, string database) - { - return []; - } + public override DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStringBuilder builder, string database) => []; - protected override Guesser GetGuesser(DatabaseTypeRequest request) - { - return new Guesser(request) + protected override Guesser GetGuesser(DatabaseTypeRequest request) => + new(request) {ExtraLengthPerNonAsciiCharacter = OracleTypeTranslater.ExtraLengthPerNonAsciiCharacter}; - } public override void CreateSchema(DiscoveredDatabase discoveredDatabase, string name) { //Oracle doesn't really have schemas especially since a User is a Database } - protected override Guesser GetGuesser(DataColumn column) - { - return new Guesser {ExtraLengthPerNonAsciiCharacter = OracleTypeTranslater.ExtraLengthPerNonAsciiCharacter}; - } - - + protected override Guesser GetGuesser(DataColumn column) => new() {ExtraLengthPerNonAsciiCharacter = OracleTypeTranslater.ExtraLengthPerNonAsciiCharacter}; } \ No newline at end of file diff --git a/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs b/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs index 9f36ad8a..8c447ec5 100644 --- a/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs @@ -34,15 +34,10 @@ public override string GetRuntimeName(string s) answer.Trim('"').ToUpper(); } - public override bool SupportsEmbeddedParameters() - { - return false; - } + public override bool SupportsEmbeddedParameters() => false; + + public override string EnsureWrappedImpl(string databaseOrTableName) => $"\"{GetRuntimeName(databaseOrTableName)}\""; - public override string EnsureWrappedImpl(string databaseOrTableName) - { - return $"\"{GetRuntimeName(databaseOrTableName)}\""; - } public override string EnsureFullyQualified(string databaseName, string schema, string tableName) { //if there is no schema address it as db..table (which is the same as db.dbo.table in Microsoft SQL Server) @@ -52,24 +47,13 @@ public override string EnsureFullyQualified(string databaseName, string schema, return $"\"{GetRuntimeName(databaseName)}\"{DatabaseTableSeparator}\"{GetRuntimeName(tableName)}\""; } - public override string EnsureFullyQualified(string databaseName, string schema, string tableName, string columnName, bool isTableValuedFunction = false) - { - return $"{EnsureFullyQualified(databaseName, schema, tableName)}.\"{GetRuntimeName(columnName)}\""; - } - public override TopXResponse HowDoWeAchieveTopX(int x) - { - return new TopXResponse($"OFFSET 0 ROWS FETCH NEXT {x} ROWS ONLY", QueryComponent.Postfix); - } + public override string EnsureFullyQualified(string databaseName, string schema, string tableName, string columnName, bool isTableValuedFunction = false) => $"{EnsureFullyQualified(databaseName, schema, tableName)}.\"{GetRuntimeName(columnName)}\""; - public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) - { - throw new NotSupportedException(); - } + public override TopXResponse HowDoWeAchieveTopX(int x) => new($"OFFSET 0 ROWS FETCH NEXT {x} ROWS ONLY", QueryComponent.Postfix); - public override HashSet GetReservedWords() - { - return ReservedWords; - } + public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) => throw new NotSupportedException(); + + public override HashSet GetReservedWords() => ReservedWords; public override string GetScalarFunctionSql(MandatoryScalarFunctions function) => function switch @@ -84,27 +68,17 @@ public override string GetScalarFunctionSql(MandatoryScalarFunctions function) = /// Works in Oracle 12c+ only https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1 /// /// - public override string GetAutoIncrementKeywordIfAny() - { + public override string GetAutoIncrementKeywordIfAny() => //this is handled in - return " GENERATED ALWAYS AS IDENTITY"; - } + " GENERATED ALWAYS AS IDENTITY"; - public override Dictionary GetSQLFunctionsDictionary() - { - return []; - } + public override Dictionary GetSQLFunctionsDictionary() => []; - public override string HowDoWeAchieveMd5(string selectSql) - { - return $"RAWTOHEX(standard_hash({selectSql}, 'MD5'))"; - } + public override string HowDoWeAchieveMd5(string selectSql) => $"RAWTOHEX(standard_hash({selectSql}, 'MD5'))"; - protected override object FormatTimespanForDbParameter(TimeSpan timeSpan) - { + protected override object FormatTimespanForDbParameter(TimeSpan timeSpan) => //Value must be a DateTime even if DBParameter is of Type DbType.Time - return Convert.ToDateTime(timeSpan.ToString()); - } + Convert.ToDateTime(timeSpan.ToString()); private static readonly HashSet ReservedWords = new( new [] { diff --git a/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs b/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs index 00b368a2..44d54f71 100644 --- a/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs @@ -22,35 +22,18 @@ private OracleServerHelper() : base(DatabaseType.Oracle) protected override string ConnectionTimeoutKeyName => "Connection Timeout"; #region Up Typing - public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) - { - return new OracleCommand(s, con as OracleConnection) {Transaction = transaction as OracleTransaction}; - } + public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => new OracleCommand(s, con as OracleConnection) {Transaction = transaction as OracleTransaction}; - public override DbDataAdapter GetDataAdapter(DbCommand cmd) - { - return new OracleDataAdapter((OracleCommand) cmd); - } + public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new OracleDataAdapter((OracleCommand) cmd); - public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) - { - return new OracleCommandBuilder((OracleDataAdapter) GetDataAdapter(cmd)); - } + public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) => new OracleCommandBuilder((OracleDataAdapter) GetDataAdapter(cmd)); - public override DbParameter GetParameter(string parameterName) - { - return new OracleParameter(parameterName,null); - } + public override DbParameter GetParameter(string parameterName) => new OracleParameter(parameterName,null); - public override DbConnection GetConnection(DbConnectionStringBuilder builder) - { - return new OracleConnection(builder.ConnectionString); - } + public override DbConnection GetConnection(DbConnectionStringBuilder builder) => new OracleConnection(builder.ConnectionString); + + protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString) => new OracleConnectionStringBuilder(connectionString); - protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString) - { - return new OracleConnectionStringBuilder(connectionString); - } #endregion protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string server, string database, string username, string password) @@ -68,11 +51,9 @@ protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(stri return toReturn; } - public override DbConnectionStringBuilder ChangeDatabase(DbConnectionStringBuilder builder, string newDatabase) - { + public override DbConnectionStringBuilder ChangeDatabase(DbConnectionStringBuilder builder, string newDatabase) => //does not apply to oracle since user = database but we create users with random passwords - return builder; - } + builder; public override DbConnectionStringBuilder EnableAsync(DbConnectionStringBuilder builder) => builder; diff --git a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs index c9e7ada2..b0fd9501 100644 --- a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs @@ -17,10 +17,7 @@ public sealed class OracleTableHelper : DiscoveredTableHelper public static readonly OracleTableHelper Instance=new(); private OracleTableHelper() {} - public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) - { - return $"SELECT * FROM {table.GetFullyQualifiedName()} OFFSET 0 ROWS FETCH NEXT {topX} ROWS ONLY"; - } + public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) => $"SELECT * FROM {table.GetFullyQualifiedName()} OFFSET 0 ROWS FETCH NEXT {topX} ROWS ONLY"; public override DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTable, IManagedConnection connection, string database) { @@ -181,15 +178,10 @@ public override void DropFunction(DbConnection connection, DiscoveredTableValued } public override IEnumerable DiscoverTableValuedFunctionParameters(DbConnection connection, - DiscoveredTableValuedFunction discoveredTableValuedFunction, DbTransaction transaction) - { + DiscoveredTableValuedFunction discoveredTableValuedFunction, DbTransaction transaction) => throw new NotImplementedException(); - } - public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable, IManagedConnection connection,CultureInfo culture) - { - return new OracleBulkCopy(discoveredTable,connection,culture); - } + public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable, IManagedConnection connection,CultureInfo culture) => new OracleBulkCopy(discoveredTable,connection,culture); public override int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, IManagedTransaction transaction = null) { @@ -317,8 +309,5 @@ protected override string GetRenameTableSql(DiscoveredTable discoveredTable, str return $@"alter table {discoveredTable.GetFullyQualifiedName()} rename to {newName}"; } - public override bool RequiresLength(string columnType) - { - return base.RequiresLength(columnType) || columnType.Equals("varchar2", StringComparison.CurrentCultureIgnoreCase); - } + public override bool RequiresLength(string columnType) => base.RequiresLength(columnType) || columnType.Equals("varchar2", StringComparison.CurrentCultureIgnoreCase); } \ No newline at end of file diff --git a/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs b/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs index 0caee472..49b6da62 100644 --- a/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs +++ b/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs @@ -53,11 +53,9 @@ private OracleTypeTranslater(): base(4000, 4000) /// protected override bool IsBit(string sqlType) => sqlType.Equals("decimal(1,0)",StringComparison.InvariantCultureIgnoreCase); - protected override bool IsString(string sqlType) - { - return !sqlType.Contains("RAW", StringComparison.InvariantCultureIgnoreCase) && - (base.IsString(sqlType) || AlsoStringRegex.IsMatch(sqlType)); - } + protected override bool IsString(string sqlType) => + !sqlType.Contains("RAW", StringComparison.InvariantCultureIgnoreCase) && + (base.IsString(sqlType) || AlsoStringRegex.IsMatch(sqlType)); protected override bool IsFloatingPoint(string sqlType) => base.IsFloatingPoint(sqlType) || AlsoFloatingPointRegex.IsMatch(sqlType); @@ -77,10 +75,7 @@ protected override bool IsInt(string sqlType) => protected override string GetDateDateTimeDataType() => "DATE"; - public override Guesser GetGuesserFor(DiscoveredColumn discoveredColumn) - { - return base.GetGuesserFor(discoveredColumn, ExtraLengthPerNonAsciiCharacter); - } + public override Guesser GetGuesserFor(DiscoveredColumn discoveredColumn) => base.GetGuesserFor(discoveredColumn, ExtraLengthPerNonAsciiCharacter); [GeneratedRegex("^([N]?CLOB)|(LONG)", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] private static partial Regex AlsoStringRegexImpl(); diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs index 5cea350f..b8df5b3b 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs @@ -116,23 +116,13 @@ FROM pg_stat_activity } - public override Dictionary DescribeDatabase(DbConnectionStringBuilder builder, string database) - { - throw new NotImplementedException(); - } + public override Dictionary DescribeDatabase(DbConnectionStringBuilder builder, string database) => throw new NotImplementedException(); - protected override string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) - { + protected override string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) => //Collations generally have to be in quotes (unless maybe they are very weird user generated ones?) + $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} {(string.IsNullOrWhiteSpace(col.Collation) ? "" : $"COLLATE \"{col.Collation.Trim('"')}\"")} {(col.AllowNulls && !col.IsPrimaryKey ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; - return - $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} {(string.IsNullOrWhiteSpace(col.Collation) ? "" : $"COLLATE \"{col.Collation.Trim('"')}\"")} {(col.AllowNulls && !col.IsPrimaryKey ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; - } - - public override DirectoryInfo Detach(DiscoveredDatabase database) - { - throw new NotImplementedException(); - } + public override DirectoryInfo Detach(DiscoveredDatabase database) => throw new NotImplementedException(); public override void CreateBackup(DiscoveredDatabase discoveredDatabase, string backupName) { diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs index adbf4d79..53a24d6f 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs @@ -15,21 +15,16 @@ private PostgreSqlServerHelper() : base(DatabaseType.PostgreSql) { } - protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString) - { - return new NpgsqlConnectionStringBuilder(connectionString); - } + protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString) => new NpgsqlConnectionStringBuilder(connectionString); protected override string ServerKeyName => "Host"; protected override string DatabaseKeyName => "Database"; protected override string ConnectionTimeoutKeyName => "Timeout"; - public override DbConnectionStringBuilder EnableAsync(DbConnectionStringBuilder builder) - { + public override DbConnectionStringBuilder EnableAsync(DbConnectionStringBuilder builder) => //nothing special we need to turn on - return builder; - } + builder; public override IDiscoveredDatabaseHelper GetDatabaseHelper() => PostgreSqlDatabaseHelper.Instance; @@ -47,20 +42,11 @@ public override void CreateDatabase(DbConnectionStringBuilder builder, IHasRunti cmd.ExecuteNonQuery(); } - public override Dictionary DescribeServer(DbConnectionStringBuilder builder) - { - throw new NotImplementedException(); - } + public override Dictionary DescribeServer(DbConnectionStringBuilder builder) => throw new NotImplementedException(); - public override string GetExplicitUsernameIfAny(DbConnectionStringBuilder builder) - { - return ((NpgsqlConnectionStringBuilder) builder).Username; - } + public override string GetExplicitUsernameIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Username; - public override string GetExplicitPasswordIfAny(DbConnectionStringBuilder builder) - { - return ((NpgsqlConnectionStringBuilder) builder).Password; - } + public override string GetExplicitPasswordIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Password; public override Version GetVersion(DiscoveredServer server) { @@ -102,30 +88,15 @@ public override string[] ListDatabases(DbConnection con) return [.. databases]; } - public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) - { - return new NpgsqlCommand(s, (NpgsqlConnection) con, (NpgsqlTransaction) transaction); - } + public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => new NpgsqlCommand(s, (NpgsqlConnection) con, (NpgsqlTransaction) transaction); - public override DbDataAdapter GetDataAdapter(DbCommand cmd) - { - return new NpgsqlDataAdapter((NpgsqlCommand) cmd); - } + public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new NpgsqlDataAdapter((NpgsqlCommand) cmd); - public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) - { - return new NpgsqlCommandBuilder(new NpgsqlDataAdapter((NpgsqlCommand) cmd)); - } + public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) => new NpgsqlCommandBuilder(new NpgsqlDataAdapter((NpgsqlCommand) cmd)); - public override DbParameter GetParameter(string parameterName) - { - return new NpgsqlParameter {ParameterName = parameterName}; - } + public override DbParameter GetParameter(string parameterName) => new NpgsqlParameter {ParameterName = parameterName}; - public override DbConnection GetConnection(DbConnectionStringBuilder builder) - { - return new NpgsqlConnection(builder.ConnectionString); - } + public override DbConnection GetConnection(DbConnectionStringBuilder builder) => new NpgsqlConnection(builder.ConnectionString); protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(string server, string database, string username, string password) diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs index 9cbba35d..72458e03 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs @@ -24,38 +24,24 @@ private PostgreSqlSyntaxHelper() : base(PostgreSqlTypeTranslater.Instance,Postgr public override string CloseQualifier => "\""; - public override bool SupportsEmbeddedParameters() - { - return false; - } - protected override object FormatDateTimeForDbParameter(DateTime dateTime) - { + public override bool SupportsEmbeddedParameters() => false; + + protected override object FormatDateTimeForDbParameter(DateTime dateTime) => // Starting with 4.0.0 npgsql crashes if it has to read a DateTime Unspecified Kind // See : https://github.com/npgsql/efcore.pg/issues/2000 // Also it doesn't support DateTime.Kind.Local + dateTime.Kind == DateTimeKind.Unspecified ? dateTime.ToUniversalTime():dateTime; - return dateTime.Kind == DateTimeKind.Unspecified ? dateTime.ToUniversalTime():dateTime; - } - - public override string EnsureWrappedImpl(string databaseOrTableName) - { - return $"\"{GetRuntimeNameWithDoubledDoubleQuotes(databaseOrTableName)}\""; - } + public override string EnsureWrappedImpl(string databaseOrTableName) => $"\"{GetRuntimeNameWithDoubledDoubleQuotes(databaseOrTableName)}\""; /// /// Returns the runtime name of the string with all double quotes escaped (but resulting string is not wrapped itself) /// /// /// - private string GetRuntimeNameWithDoubledDoubleQuotes(string s) - { - return GetRuntimeName(s)?.Replace("\"","\"\""); - } + private string GetRuntimeNameWithDoubledDoubleQuotes(string s) => GetRuntimeName(s)?.Replace("\"","\"\""); - protected override string UnescapeWrappedNameBody(string name) - { - return name.Replace("\"\"","\""); - } + protected override string UnescapeWrappedNameBody(string name) => name.Replace("\"\"","\""); public override string EnsureFullyQualified(string databaseName, string schema, string tableName) { @@ -77,15 +63,9 @@ public override string EnsureFullyQualified(string databaseName, string schema, } - public override TopXResponse HowDoWeAchieveTopX(int x) - { - return new TopXResponse($"fetch first {x} rows only", QueryComponent.Postfix); - } + public override TopXResponse HowDoWeAchieveTopX(int x) => new($"fetch first {x} rows only", QueryComponent.Postfix); - public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) - { - throw new NotSupportedException(); - } + public override string GetParameterDeclaration(string proposedNewParameterName, string sqlType) => throw new NotSupportedException(); public override string GetScalarFunctionSql(MandatoryScalarFunctions function) => function switch @@ -97,23 +77,11 @@ public override string GetScalarFunctionSql(MandatoryScalarFunctions function) = _ => throw new ArgumentOutOfRangeException(nameof(function)) }; - public override string GetAutoIncrementKeywordIfAny() - { - return "GENERATED ALWAYS AS IDENTITY"; - } + public override string GetAutoIncrementKeywordIfAny() => "GENERATED ALWAYS AS IDENTITY"; - public override Dictionary GetSQLFunctionsDictionary() - { - return []; - } + public override Dictionary GetSQLFunctionsDictionary() => []; - public override string HowDoWeAchieveMd5(string selectSql) - { - return $"MD5({selectSql})"; - } + public override string HowDoWeAchieveMd5(string selectSql) => $"MD5({selectSql})"; - public override string GetDefaultSchemaIfAny() - { - return "public"; - } + public override string GetDefaultSchemaIfAny() => "public"; } \ No newline at end of file diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs index b6fcca38..b822bc86 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs @@ -16,10 +16,7 @@ public sealed class PostgreSqlTableHelper : DiscoveredTableHelper { public static readonly PostgreSqlTableHelper Instance = new(); private PostgreSqlTableHelper() {} - public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) - { - return $"SELECT * FROM {table.GetFullyQualifiedName()} FETCH FIRST {topX} ROWS ONLY"; - } + public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX) => $"SELECT * FROM {table.GetFullyQualifiedName()} FETCH FIRST {topX} ROWS ONLY"; public override DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTable, IManagedConnection connection, string database) { @@ -127,10 +124,7 @@ private string GetSQLType_FromSpColumnsResult(DbDataReader r) if (HasPrecisionAndScale(columnType)) lengthQualifier = $"({r["numeric_precision"]},{r["numeric_scale"]})"; else - if (r["character_maximum_length"] != DBNull.Value) - { - lengthQualifier = $"({Convert.ToInt32(r["character_maximum_length"])})"; - } + if (r["character_maximum_length"] != DBNull.Value) lengthQualifier = $"({Convert.ToInt32(r["character_maximum_length"])})"; return columnType + lengthQualifier; } diff --git a/Tests/FAnsiTests/Aggregation/AggregationTests.cs b/Tests/FAnsiTests/Aggregation/AggregationTests.cs index 30c13cb1..0be37af1 100644 --- a/Tests/FAnsiTests/Aggregation/AggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/AggregationTests.cs @@ -58,7 +58,6 @@ private void SetupDatabaseTable(bool easy, string name) foreach (var (key, _) in TestConnectionStrings) - { try { var db = GetTestDatabase(key); @@ -74,8 +73,6 @@ private void SetupDatabaseTable(bool easy, string name) TestContext.WriteLine(e); } - - } } catch (Exception e) { diff --git a/Tests/FAnsiTests/CrossPlatformTests.cs b/Tests/FAnsiTests/CrossPlatformTests.cs index 8d663247..7f1f9e32 100644 --- a/Tests/FAnsiTests/CrossPlatformTests.cs +++ b/Tests/FAnsiTests/CrossPlatformTests.cs @@ -1094,7 +1094,6 @@ public void Test_BulkInserting_LotsOfDates(DatabaseType type) //test basic insert foreach(var s in someDates) - { tbl.Insert(new Dictionary { {"ID",1}, @@ -1102,7 +1101,6 @@ public void Test_BulkInserting_LotsOfDates(DatabaseType type) {"MyString",Guid.NewGuid().ToString()} },culture ); - } using var dt = new DataTable(); diff --git a/Tests/FAnsiTests/DatabaseTests.cs b/Tests/FAnsiTests/DatabaseTests.cs index 12981cc0..4a636c14 100644 --- a/Tests/FAnsiTests/DatabaseTests.cs +++ b/Tests/FAnsiTests/DatabaseTests.cs @@ -100,10 +100,8 @@ protected DiscoveredDatabase GetTestDatabase(DatabaseType type, bool cleanDataba if(_allowDatabaseCreation) db.Create(); else - { Assert.Inconclusive( $"Database {_testScratchDatabase} did not exist on server {server} and AllowDatabaseCreation was false in {TestFilename}"); - } else { if (!cleanDatabase) return db; diff --git a/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs b/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs index 2b102538..253d90e1 100644 --- a/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs +++ b/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs @@ -69,7 +69,6 @@ public void SyntaxHelperTest_GetRuntimeName_MultipleCalls(DatabaseType dbType, var currentName = runtime; for(var i=0;i<10;i++) - { if(i%2 ==0 ) { Assert.That(currentName, Is.EqualTo(runtime)); @@ -84,7 +83,6 @@ public void SyntaxHelperTest_GetRuntimeName_MultipleCalls(DatabaseType dbType, currentName = syntaxHelper.GetRuntimeName(currentName); currentName = syntaxHelper.GetRuntimeName(currentName); } - } } [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] diff --git a/Tests/FAnsiTests/Table/BulkInsertTest.cs b/Tests/FAnsiTests/Table/BulkInsertTest.cs index b96d8655..c990b20d 100644 --- a/Tests/FAnsiTests/Table/BulkInsertTest.cs +++ b/Tests/FAnsiTests/Table/BulkInsertTest.cs @@ -421,11 +421,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas dt.Columns.Add("peter"); dt.Columns.Add("bob"); - for (var i = 0; i < 30; i++) - { - dt.Columns.Add($"Column{i}"); - } - + for (var i = 0; i < 30; i++) dt.Columns.Add($"Column{i}"); for (var i = 0; i < numberOfRowsPerBatch; i++) diff --git a/Tests/FAnsiTests/Table/TableTypeTests.cs b/Tests/FAnsiTests/Table/TableTypeTests.cs index 11fd5114..0ced015f 100644 --- a/Tests/FAnsiTests/Table/TableTypeTests.cs +++ b/Tests/FAnsiTests/Table/TableTypeTests.cs @@ -27,10 +27,7 @@ public void CreateView(DatabaseType dbType) var syntax = tbl.GetQuerySyntaxHelper(); //oracle likes to create stuff under your user account not the database your actually using! - if(dbType == DatabaseType.Oracle) - { - viewName = syntax.EnsureFullyQualified(tbl.Database.GetRuntimeName(),null,"MyView"); - } + if(dbType == DatabaseType.Oracle) viewName = syntax.EnsureFullyQualified(tbl.Database.GetRuntimeName(),null,"MyView"); var sql = string.Format(@"CREATE VIEW {0} AS SELECT {2} diff --git a/Tests/FAnsiTests/TypeTranslation/GuesserExtensions.cs b/Tests/FAnsiTests/TypeTranslation/GuesserExtensions.cs index 3331ee93..329600d7 100644 --- a/Tests/FAnsiTests/TypeTranslation/GuesserExtensions.cs +++ b/Tests/FAnsiTests/TypeTranslation/GuesserExtensions.cs @@ -5,8 +5,5 @@ namespace FAnsiTests.TypeTranslation; public static class GuesserExtensions { - public static string GetSqlDBType(this Guesser guesser, ITypeTranslater tt) - { - return tt.GetSQLDBTypeForCSharpType(guesser.Guess); - } + public static string GetSqlDBType(this Guesser guesser, ITypeTranslater tt) => tt.GetSQLDBTypeForCSharpType(guesser.Guess); } \ No newline at end of file diff --git a/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs b/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs index c60ebc73..42dd053e 100644 --- a/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs +++ b/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs @@ -28,7 +28,6 @@ public sealed class TypeTranslaterTests : DatabaseTests public void SetupDatabases() { foreach (DatabaseType type in Enum.GetValues(typeof(DatabaseType))) - { try { var tt = ImplementationManager.GetImplementation(type).GetQuerySyntaxHelper().TypeTranslater; @@ -38,7 +37,6 @@ public void SetupDatabases() { //no implementation for this Type } - } } [TestCase(DatabaseType.MicrosoftSQLServer,"varchar(10)")] From 7cec8f9fb6cdf4883e9c7ecc2243ce2e6b7833a6 Mon Sep 17 00:00:00 2001 From: James A Sutherland <> Date: Thu, 1 Feb 2024 11:01:57 -0600 Subject: [PATCH 3/7] Bump TypeGuesser to 1.2.2 --- FAnsiSql/FAnsi.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FAnsiSql/FAnsi.csproj b/FAnsiSql/FAnsi.csproj index 8c21f070..17eac26c 100644 --- a/FAnsiSql/FAnsi.csproj +++ b/FAnsiSql/FAnsi.csproj @@ -34,7 +34,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -75,4 +75,4 @@ - \ No newline at end of file + From 503677c2f1c878b3eb508210ca4993bd72a1fae0 Mon Sep 17 00:00:00 2001 From: James A Sutherland <> Date: Thu, 1 Feb 2024 11:02:07 -0600 Subject: [PATCH 4/7] Enable nullable annotations --- Directory.Build.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 84e47896..f2ad2f8c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,6 @@ preview - + enable + \ No newline at end of file From 87c725a7463ad80a47744b0f02e1d2ee77789f34 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 1 Feb 2024 12:13:54 -0600 Subject: [PATCH 5/7] Nullable fixups --- .github/workflows/dotnet-core.yml | 2 +- FAnsiSql/Connections/IManagedConnection.cs | 2 +- FAnsiSql/Connections/ManagedConnection.cs | 2 +- FAnsiSql/DatabaseOperationArgs.cs | 2 +- FAnsiSql/Discovery/BulkCopy.cs | 11 ++-- .../ConnectionStringKeywordAccumulator.cs | 2 +- .../Constraints/DiscoveredRelationship.cs | 2 +- FAnsiSql/Discovery/DatabaseColumnRequest.cs | 8 +-- FAnsiSql/Discovery/DiscoveredColumn.cs | 5 +- FAnsiSql/Discovery/DiscoveredDataType.cs | 35 ++++++------ FAnsiSql/Discovery/DiscoveredDatabase.cs | 22 ++++---- .../Discovery/DiscoveredDatabaseHelper.cs | 19 +++---- FAnsiSql/Discovery/DiscoveredServer.cs | 12 ++--- FAnsiSql/Discovery/DiscoveredServerHelper.cs | 12 ++--- FAnsiSql/Discovery/DiscoveredTable.cs | 42 +++++++-------- FAnsiSql/Discovery/DiscoveredTableHelper.cs | 20 +++---- .../DiscoveredTableValuedFunction.cs | 6 +-- .../Discovery/IDiscoveredDatabaseHelper.cs | 9 ++-- FAnsiSql/Discovery/IDiscoveredServerHelper.cs | 7 +-- FAnsiSql/Discovery/IDiscoveredTableHelper.cs | 8 +-- FAnsiSql/Discovery/IMightNotExist.cs | 2 +- .../AggregateCustomLineCollection.cs | 4 +- .../Aggregation/AggregateHelper.cs | 4 +- .../Aggregation/IAggregateHelper.cs | 2 +- .../QuerySyntax/IQuerySyntaxHelper.cs | 19 +++---- FAnsiSql/Discovery/QuerySyntaxHelper.cs | 53 ++++++++----------- .../TableCreation/CreateTableArgs.cs | 11 ++-- .../MicrosoftSQLAggregateHelper.cs | 4 +- .../MicrosoftSQL/MicrosoftSQLBulkCopy.cs | 23 ++++---- .../MicrosoftSQLDatabaseHelper.cs | 4 +- .../MicrosoftSQL/MicrosoftSQLServerHelper.cs | 2 +- .../MicrosoftSQL/MicrosoftSQLTableHelper.cs | 2 +- .../Implementations/MySql/MySqlBulkCopy.cs | 7 ++- .../MySql/MySqlDatabaseHelper.cs | 18 +++---- .../MySql/MySqlServerHelper.cs | 2 +- .../Implementations/MySql/MySqlTableHelper.cs | 4 +- .../Oracle/OracleDatabaseHelper.cs | 4 +- .../Oracle/OracleServerHelper.cs | 2 +- .../Oracle/OracleTableHelper.cs | 10 ++-- .../Aggregation/PostgreSqlAggregateHelper.cs | 4 +- .../PostgreSql/PostgreSqlDatabaseHelper.cs | 4 +- .../PostgreSql/PostgreSqlServerHelper.cs | 7 +-- .../PostgreSql/PostgreSqlTableHelper.cs | 4 +- .../Aggregation/AggregationTests.cs | 6 +-- .../CalendarWithPivotAggregationTests.cs | 12 ++--- Tests/FAnsiTests/DatabaseTests.cs | 10 ++-- .../EqualityTests_ServerAndDatabase.cs | 5 +- .../Equality/EqualityTests_TableAndColumn.cs | 4 +- Tests/FAnsiTests/PackageListIsCorrectTests.cs | 4 +- .../Query/QuerySyntaxHelperTests.cs | 19 +++---- Tests/FAnsiTests/Server/ServerTests.cs | 4 +- Tests/FAnsiTests/Table/BulkInsertTest.cs | 13 +++-- Tests/FAnsiTests/Table/CreateTableTests.cs | 2 +- .../FAnsiTests/Table/DataTypeAdjusterTests.cs | 4 +- 54 files changed, 252 insertions(+), 255 deletions(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index db623725..102adbf9 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -38,7 +38,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v4 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x - name: Install Sql Server run: | wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - diff --git a/FAnsiSql/Connections/IManagedConnection.cs b/FAnsiSql/Connections/IManagedConnection.cs index 41ecbefd..ef3ae5ba 100644 --- a/FAnsiSql/Connections/IManagedConnection.cs +++ b/FAnsiSql/Connections/IManagedConnection.cs @@ -17,7 +17,7 @@ public interface IManagedConnection : IDisposable /// /// Optional - DbTransaction being wrapped if one has been started or null /// - DbTransaction Transaction { get; } + DbTransaction? Transaction { get; } /// /// Optional - transaction being run (See . If this is not null then should also be not null. diff --git a/FAnsiSql/Connections/ManagedConnection.cs b/FAnsiSql/Connections/ManagedConnection.cs index 7fc8166a..65f8a242 100644 --- a/FAnsiSql/Connections/ManagedConnection.cs +++ b/FAnsiSql/Connections/ManagedConnection.cs @@ -12,7 +12,7 @@ public sealed class ManagedConnection : IManagedConnection public DbConnection Connection { get; } /// - public DbTransaction Transaction { get; } + public DbTransaction? Transaction { get; } /// public IManagedTransaction ManagedTransaction { get; } diff --git a/FAnsiSql/DatabaseOperationArgs.cs b/FAnsiSql/DatabaseOperationArgs.cs index fd97f0aa..087de035 100644 --- a/FAnsiSql/DatabaseOperationArgs.cs +++ b/FAnsiSql/DatabaseOperationArgs.cs @@ -16,7 +16,7 @@ public sealed class DatabaseOperationArgs /// /// If using an ongoing connection/transaction. Otherwise null. /// - public IManagedTransaction TransactionIfAny{ get; set; } + public IManagedTransaction? TransactionIfAny { get; set; } /// /// Time to allow to run before cancelling (this is db timeout and doesn't affect ) diff --git a/FAnsiSql/Discovery/BulkCopy.cs b/FAnsiSql/Discovery/BulkCopy.cs index 5206d9df..a26c227a 100644 --- a/FAnsiSql/Discovery/BulkCopy.cs +++ b/FAnsiSql/Discovery/BulkCopy.cs @@ -40,7 +40,7 @@ public abstract class BulkCopy:IBulkCopy public bool AllowUnmatchedInputColumns { get; private set; } /// - public DateTimeTypeDecider DateTimeDecider {get; protected set; } + public DateTimeTypeDecider DateTimeDecider { get; protected set; } /// /// Begins a new bulk copy operation in which one or more data tables are uploaded to the . The API entrypoint for this is @@ -50,7 +50,7 @@ public abstract class BulkCopy:IBulkCopy /// /// /// For parsing string date expressions etc - protected BulkCopy(DiscoveredTable targetTable, IManagedConnection connection,CultureInfo culture) + protected BulkCopy(DiscoveredTable targetTable, IManagedConnection connection, CultureInfo culture) { Culture = culture; TargetTable = targetTable; @@ -121,11 +121,11 @@ protected void ConvertStringTypesToHardTypes(DataTable dt) var newColumn = dt.Columns.Add($"{dataColumn.ColumnName}_{Guid.NewGuid()}",dataType); //if it's a DateTime decider then guess DateTime culture based on values in the table - if(decider is DateTimeTypeDecider) + if (decider is DateTimeTypeDecider) { //also use this one in case the user has set up explicit stuff on it e.g. Culture/Settings decider = DateTimeDecider; - DateTimeDecider.GuessDateFormat(dt.Rows.Cast().Take(500).Select(r=>r[dataColumn] as string)); + DateTimeDecider.GuessDateFormat(dt.Rows.Cast().Take(500).Select(r => r[dataColumn] as string).OfType()); } @@ -134,9 +134,8 @@ protected void ConvertStringTypesToHardTypes(DataTable dt) { //parse the value dr[newColumn] = decider.Parse(dr[dataColumn] as string)??DBNull.Value; - } - catch(Exception ex) + catch (Exception ex) { throw new Exception($"Failed to parse value '{dr[dataColumn]}' in column '{dataColumn}'",ex); } diff --git a/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs b/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs index 2bdc6386..60467eb2 100644 --- a/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs +++ b/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs @@ -61,7 +61,7 @@ public void AddOrUpdateKeyword(string keyword, string value, ConnectionStringKey /// /// /// - private string GetCollisionWithKeyword(string keyword, string value) + private string? GetCollisionWithKeyword(string keyword, string value) { ArgumentNullException.ThrowIfNull(keyword); ArgumentNullException.ThrowIfNull(value); diff --git a/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs b/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs index c40d457d..3c74a05e 100644 --- a/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs +++ b/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs @@ -52,7 +52,7 @@ public sealed class DiscoveredRelationship(string fkName, DiscoveredTable pkTabl /// /// /// - public void AddKeys(string primaryKeyCol, string foreignKeyCol,IManagedTransaction transaction = null) + public void AddKeys(string primaryKeyCol, string foreignKeyCol,IManagedTransaction? transaction = null) { if (_pkColumns == null) { diff --git a/FAnsiSql/Discovery/DatabaseColumnRequest.cs b/FAnsiSql/Discovery/DatabaseColumnRequest.cs index aec0858a..eae478e5 100644 --- a/FAnsiSql/Discovery/DatabaseColumnRequest.cs +++ b/FAnsiSql/Discovery/DatabaseColumnRequest.cs @@ -11,7 +11,7 @@ namespace FAnsi.Discovery; /// /// Type specification is defined in the DatabaseTypeRequest but can also be specified explicitly (e.g. 'varchar(10)'). /// -public sealed class DatabaseColumnRequest(string columnName, DatabaseTypeRequest typeRequested, bool allowNulls = true) +public sealed class DatabaseColumnRequest(string columnName, DatabaseTypeRequest? typeRequested, bool allowNulls = true) : ISupplementalColumnInformation, IHasRuntimeName { /// @@ -19,7 +19,7 @@ public sealed class DatabaseColumnRequest(string columnName, DatabaseTypeRequest /// /// See also /// - public string ExplicitDbType { get; set; } + public string? ExplicitDbType { get; set; } public string ColumnName { get; set; } = columnName; @@ -31,7 +31,7 @@ public sealed class DatabaseColumnRequest(string columnName, DatabaseTypeRequest /// /// See also /// - public DatabaseTypeRequest TypeRequested { get; set; } = typeRequested; + public DatabaseTypeRequest? TypeRequested { get; set; } = typeRequested; /// /// True to create a column which is nullable @@ -59,7 +59,7 @@ public sealed class DatabaseColumnRequest(string columnName, DatabaseTypeRequest /// public string Collation { get; set; } - public DatabaseColumnRequest(string columnName, string explicitDbType, bool allowNulls = true) : this(columnName, (DatabaseTypeRequest)null, allowNulls) + public DatabaseColumnRequest(string columnName, string explicitDbType, bool allowNulls = true) : this(columnName, (DatabaseTypeRequest?)null, allowNulls) { ExplicitDbType = explicitDbType; } diff --git a/FAnsiSql/Discovery/DiscoveredColumn.cs b/FAnsiSql/Discovery/DiscoveredColumn.cs index f3b5ab1d..e75fb686 100644 --- a/FAnsiSql/Discovery/DiscoveredColumn.cs +++ b/FAnsiSql/Discovery/DiscoveredColumn.cs @@ -13,7 +13,8 @@ namespace FAnsi.Discovery; /// /// /// -public sealed class DiscoveredColumn(DiscoveredTable table, string name, bool allowsNulls) : IHasFullyQualifiedNameToo,ISupplementalColumnInformation +public sealed class DiscoveredColumn(DiscoveredTable table, string name, bool allowsNulls) : IHasFullyQualifiedNameToo, + ISupplementalColumnInformation { /// /// The on which the was found @@ -105,7 +106,7 @@ public sealed class DiscoveredColumn(DiscoveredTable table, string name, bool al /// /// /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/FAnsiSql/Discovery/DiscoveredDataType.cs b/FAnsiSql/Discovery/DiscoveredDataType.cs index eea36229..a0bb12d8 100644 --- a/FAnsiSql/Discovery/DiscoveredDataType.cs +++ b/FAnsiSql/Discovery/DiscoveredDataType.cs @@ -14,7 +14,7 @@ namespace FAnsi.Discovery; /// public sealed class DiscoveredDataType { - private readonly DiscoveredColumn Column; + private readonly DiscoveredColumn? _column; /// /// The proprietary DBMS name for the datatype e.g. varchar2(100) for Oracle, datetime2 for Sql Server etc. @@ -32,10 +32,10 @@ public sealed class DiscoveredDataType /// All the values in r will be copied into the Dictionary property of this class called ProprietaryDatatype /// Your inferred SQL data type for it e.g. varchar(50) /// The column it belongs to, can be null e.g. if your data type belongs to a DiscoveredParameter instead - public DiscoveredDataType(DbDataReader r, string sqlType, DiscoveredColumn column) + public DiscoveredDataType(DbDataReader r, string sqlType, DiscoveredColumn? column) { SQLType = sqlType; - Column = column; + _column = column; for (var i = 0; i < r.FieldCount; i++) ProprietaryDatatype.Add(r.GetName(i), r.GetValue(i)); @@ -46,7 +46,7 @@ public DiscoveredDataType(DbDataReader r, string sqlType, DiscoveredColumn colum /// Returns if the string type has no real limit e.g. "text" /// /// - public int GetLengthIfString() => Column.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetLengthIfString(SQLType); + public int GetLengthIfString() => _column?.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetLengthIfString(SQLType) ?? -1; /// /// Returns the Scale/Precision of the data type. Only applies to decimal(x,y) types not basic types e.g. int. @@ -54,14 +54,14 @@ public DiscoveredDataType(DbDataReader r, string sqlType, DiscoveredColumn colum /// Returns null if the datatype is not floating point /// /// - public DecimalSize GetDecimalSize() => Column.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetDigitsBeforeAndAfterDecimalPointIfDecimal(SQLType); + public DecimalSize? GetDecimalSize() => _column?.Table.Database.Server.Helper.GetQuerySyntaxHelper().TypeTranslater.GetDigitsBeforeAndAfterDecimalPointIfDecimal(SQLType); /// /// Returns the System.Type that should be used to store values read out of columns of this data type (See /// /// - [return:DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties|DynamicallyAccessedMemberTypes.PublicFields)] - public Type GetCSharpDataType() => Column.Table.Database.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(SQLType); + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] + public Type? GetCSharpDataType() => _column?.Table.Database.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(SQLType); /// /// Returns the @@ -78,7 +78,7 @@ public DiscoveredDataType(DbDataReader r, string sqlType, DiscoveredColumn colum /// /// /// - public void Resize(int newSize, IManagedTransaction managedTransaction = null) + public void Resize(int newSize, IManagedTransaction? managedTransaction = null) { var toReplace = GetLengthIfString(); @@ -104,7 +104,7 @@ public void Resize(int newSize, IManagedTransaction managedTransaction = null) /// /// /// - public void Resize(int numberOfDigitsBeforeDecimalPoint, int numberOfDigitsAfterDecimalPoint, IManagedTransaction managedTransaction = null) + public void Resize(int numberOfDigitsBeforeDecimalPoint, int numberOfDigitsAfterDecimalPoint, IManagedTransaction? managedTransaction = null) { var toReplace = GetDecimalSize(); @@ -117,9 +117,10 @@ public void Resize(int numberOfDigitsBeforeDecimalPoint, int numberOfDigitsAfter if (toReplace.NumbersAfterDecimalPlace> numberOfDigitsAfterDecimalPoint) throw new InvalidResizeException(string.Format(FAnsiStrings.DiscoveredDataType_Resize_Cannot_shrink_column__number_of_digits_after_the_decimal_point_is_currently__0__and_you_asked_to_set_it_to__1___Current_SQLType_is__2__, toReplace.NumbersAfterDecimalPlace, numberOfDigitsAfterDecimalPoint, SQLType)); - var newDataType = Column.Table.GetQuerySyntaxHelper() - .TypeTranslater.GetSQLDBTypeForCSharpType(new DatabaseTypeRequest(typeof (decimal), null, - new DecimalSize(numberOfDigitsBeforeDecimalPoint, numberOfDigitsAfterDecimalPoint))); + var newDataType = _column?.Table.GetQuerySyntaxHelper() + .TypeTranslater.GetSQLDBTypeForCSharpType(new DatabaseTypeRequest(typeof(decimal), null, + new DecimalSize(numberOfDigitsBeforeDecimalPoint, numberOfDigitsAfterDecimalPoint))) ?? + throw new InvalidOperationException($"Failed to calculate new DB type"); AlterTypeTo(newDataType, managedTransaction); } @@ -133,15 +134,15 @@ public void Resize(int numberOfDigitsBeforeDecimalPoint, int numberOfDigitsAfter /// /// The time to wait before giving up on the command (See /// - public void AlterTypeTo(string newType, IManagedTransaction managedTransaction = null,int alterTimeoutInSeconds = 500) + public void AlterTypeTo(string newType, IManagedTransaction? managedTransaction = null,int alterTimeoutInSeconds = 500) { - if(Column == null) + if(_column == null) throw new NotSupportedException(FAnsiStrings.DiscoveredDataType_AlterTypeTo_Cannot_resize_DataType_because_it_does_not_have_a_reference_to_a_Column_to_which_it_belongs); - var server = Column.Table.Database.Server; + var server = _column.Table.Database.Server; using (var connection = server.GetManagedConnection(managedTransaction)) { - var sql = Column.Helper.GetAlterColumnToSql(Column, newType, Column.AllowNulls); + var sql = _column.Helper.GetAlterColumnToSql(_column, newType, _column.AllowNulls); try { using var cmd = server.Helper.GetCommand(sql, connection.Connection, connection.Transaction); @@ -174,7 +175,7 @@ public void AlterTypeTo(string newType, IManagedTransaction managedTransaction = /// Equality based on /// /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/FAnsiSql/Discovery/DiscoveredDatabase.cs b/FAnsiSql/Discovery/DiscoveredDatabase.cs index 9eab475b..2b24ed27 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabase.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabase.cs @@ -52,7 +52,7 @@ internal DiscoveredDatabase(DiscoveredServer server, string database, IQuerySynt /// true to also return views (See ) /// Optional - if provided the database query will be sent using the connection/transaction provided /// - public DiscoveredTable[] DiscoverTables(bool includeViews, IManagedTransaction transaction = null) + public DiscoveredTable[] DiscoverTables(bool includeViews, IManagedTransaction? transaction = null) { using var managedConnection = Server.GetManagedConnection(transaction); return @@ -66,7 +66,7 @@ public DiscoveredTable[] DiscoverTables(bool includeViews, IManagedTransaction t /// /// Optional - if provided the database query will be sent using the connection/transaction provided /// - public IEnumerable DiscoverTableValuedFunctions(IManagedTransaction transaction = null) + public IEnumerable DiscoverTableValuedFunctions(IManagedTransaction? transaction = null) { using var managedConnection = Server.GetManagedConnection(transaction); return @@ -97,7 +97,7 @@ public IEnumerable DiscoverTableValuedFunctions(I /// If in doubt leave blank /// What you are looking for (normal table, view or table valued function) /// - public DiscoveredTable ExpectTable(string tableName, string schema = null, TableType tableType = TableType.Table) + public DiscoveredTable ExpectTable(string tableName, string? schema = null, TableType tableType = TableType.Table) { if (tableType == TableType.TableValuedFunction) return ExpectTableValuedFunction(tableName, schema); @@ -106,7 +106,7 @@ public DiscoveredTable ExpectTable(string tableName, string schema = null, Table } /// - public DiscoveredTableValuedFunction ExpectTableValuedFunction(string tableName,string schema = null) => new(this, tableName, _querySyntaxHelper, schema); + public DiscoveredTableValuedFunction ExpectTableValuedFunction(string tableName,string? schema = null) => new(this, tableName, _querySyntaxHelper, schema); /// /// Connects to the database and returns a list of stored proceedures found as objects @@ -125,7 +125,7 @@ public DiscoveredTable ExpectTable(string tableName, string schema = null, Table /// /// Database level operations are usually not transaction bound so be very careful about setting a parameter for this /// - public bool Exists(IManagedTransaction transaction = null) + public bool Exists(IManagedTransaction? transaction = null) { return Server.DiscoverDatabases().Any(db => db.GetRuntimeName().Equals(GetRuntimeName(),StringComparison.InvariantCultureIgnoreCase)); } @@ -169,7 +169,7 @@ public void Create(bool dropFirst = false) /// If in doubt leave blank /// Last minute delegate class for modifying the data types prior to executing SQL /// The table created - public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, string schema = null, IDatabaseColumnRequestAdjuster adjuster = null) => + public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, string? schema = null, IDatabaseColumnRequestAdjuster? adjuster = null) => CreateTable(new CreateTableArgs(this,tableName, schema) { Adjuster = adjuster, @@ -191,7 +191,7 @@ public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] col /// /// True to set CASCADE DELETE on the foreign key created by /// The table created - public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete, IDatabaseColumnRequestAdjuster adjuster = null) => + public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete, IDatabaseColumnRequestAdjuster? adjuster = null) => CreateTable(new CreateTableArgs(this, tableName, null, foreignKeyPairs, cascadeDelete) { Adjuster = adjuster, @@ -209,8 +209,8 @@ public DiscoveredTable CreateTable(string tableName, DatabaseColumnRequest[] col /// Last minute delegate class for modifying the table columns data types prior to executing SQL /// Optional - Override descisions made about columns in the by specify an explicit type etc /// The table created - public DiscoveredTable CreateTable(string tableName, DataTable dt, DatabaseColumnRequest[] explicitColumnDefinitions = null, bool createEmpty = false,IDatabaseColumnRequestAdjuster adjuster = null) => - CreateTable(new CreateTableArgs(this, tableName, null,dt,createEmpty) + public DiscoveredTable CreateTable(string tableName, DataTable dt, DatabaseColumnRequest[]? explicitColumnDefinitions = null, bool createEmpty = false,IDatabaseColumnRequestAdjuster? adjuster = null) => + CreateTable(new CreateTableArgs(this, tableName, null, dt, createEmpty) { ExplicitColumnDefinitions = explicitColumnDefinitions, Adjuster = adjuster @@ -231,7 +231,7 @@ public DiscoveredTable CreateTable(string tableName, DataTable dt, DatabaseColum /// /// /// - public DiscoveredTable CreateTable(out Dictionary typeDictionary, string tableName, DataTable dt, DatabaseColumnRequest[] explicitColumnDefinitions = null, bool createEmpty = false, IDatabaseColumnRequestAdjuster adjuster = null) + public DiscoveredTable CreateTable(out Dictionary typeDictionary, string tableName, DataTable dt, DatabaseColumnRequest[]? explicitColumnDefinitions = null, bool createEmpty = false, IDatabaseColumnRequestAdjuster? adjuster = null) { var args = new CreateTableArgs(this, tableName, null, dt, createEmpty) { @@ -290,7 +290,7 @@ public void CreateBackup(string backupName) /// /// /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs index 877d04b9..04b44209 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs @@ -22,10 +22,10 @@ namespace FAnsi.Discovery; public abstract class DiscoveredDatabaseHelper:IDiscoveredDatabaseHelper { public abstract IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, - string database, bool includeViews, DbTransaction transaction = null); + string database, bool includeViews, DbTransaction? transaction = null); public abstract IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, - DbConnection connection, string database, DbTransaction transaction = null); + DbConnection connection, string database, DbTransaction? transaction = null); public abstract DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStringBuilder builder, string database); public abstract IDiscoveredTableHelper GetTableHelper(); @@ -61,8 +61,8 @@ public DiscoveredTable CreateTable(CreateTableArgs args) //Type requested is a proper FAnsi type (e.g. string, at least 5 long) var request = overriding.TypeRequested; - if(request == null) - if(!string.IsNullOrWhiteSpace(overriding.ExplicitDbType)) + if (request is null) + if (!string.IsNullOrWhiteSpace(overriding.ExplicitDbType)) { //Type is for an explicit SQL Type e.g. varchar(5) @@ -70,7 +70,6 @@ public DiscoveredTable CreateTable(CreateTableArgs args) var tt = args.Database.Server.GetQuerySyntaxHelper().TypeTranslater; request = tt.GetDataTypeRequestForSQLDBType(overriding.ExplicitDbType); - } else throw new Exception(string.Format(FAnsiStrings.DiscoveredDatabaseHelper_CreateTable_DatabaseColumnRequestMustHaveEitherTypeRequestedOrExplicitDbType, column)); @@ -170,7 +169,9 @@ public void ThrowIfObjectColumns(DataTable dt) protected virtual Guesser GetGuesser(DatabaseTypeRequest request) => new(request); - public virtual string GetCreateTableSql(DiscoveredDatabase database, string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete, string schema) + public virtual string GetCreateTableSql(DiscoveredDatabase database, string tableName, + DatabaseColumnRequest[] columns, Dictionary? foreignKeyPairs, + bool cascadeDelete, string? schema) { if (string.IsNullOrWhiteSpace(tableName)) throw new ArgumentNullException(nameof(tableName),FAnsiStrings.DiscoveredDatabaseHelper_GetCreateTableSql_Table_name_cannot_be_null); @@ -209,7 +210,7 @@ public virtual string GetCreateTableSql(DiscoveredDatabase database, string tabl { bodySql.AppendLine(); bodySql.AppendLine(GetForeignKeyConstraintSql(tableName, syntaxHelper, - foreignKeyPairs.ToDictionary(static k => (IHasRuntimeName) k.Key, static v => v.Value), cascadeDelete, null)); + foreignKeyPairs.ToDictionary(static k => (IHasRuntimeName)k.Key, static v => v.Value), cascadeDelete, null)); } var toReturn = bodySql.ToString().TrimEnd('\r', '\n', ','); @@ -229,7 +230,7 @@ public virtual string GetCreateTableSql(DiscoveredDatabase database, string tabl protected virtual string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) => $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} {(string.IsNullOrWhiteSpace(col.Collation) ? "" : $"COLLATE {col.Collation}")} {(col.AllowNulls && !col.IsPrimaryKey ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; public virtual string GetForeignKeyConstraintSql(string foreignTable, IQuerySyntaxHelper syntaxHelper, - Dictionary foreignKeyPairs, bool cascadeDelete, string constraintName) + Dictionary foreignKeyPairs, bool cascadeDelete, string? constraintName) { var primaryKeyTable = foreignKeyPairs.Values.Select(static v => v.Table).Distinct().Single(); @@ -266,7 +267,7 @@ private static string MakeSensibleConstraintName(string prefix, string tableName return $"{prefix}{constraintName}"; } - public void ExecuteBatchNonQuery(string sql, DbConnection conn, DbTransaction transaction = null, int timeout = 30) + public void ExecuteBatchNonQuery(string sql, DbConnection conn, DbTransaction? transaction = null, int timeout = 30) { ExecuteBatchNonQuery(sql, conn, transaction, out _, timeout); } diff --git a/FAnsiSql/Discovery/DiscoveredServer.cs b/FAnsiSql/Discovery/DiscoveredServer.cs index 0392f4e0..b111d554 100644 --- a/FAnsiSql/Discovery/DiscoveredServer.cs +++ b/FAnsiSql/Discovery/DiscoveredServer.cs @@ -73,7 +73,7 @@ public DiscoveredServer(DbConnectionStringBuilder builder) /// /// /// - public DiscoveredServer(string connectionString, DatabaseType databaseType) + public DiscoveredServer(string? connectionString, DatabaseType databaseType) { Helper = ImplementationManager.GetImplementation(databaseType).GetServerHelper(); Builder = Helper.GetConnectionStringBuilder(connectionString); @@ -107,7 +107,7 @@ public DiscoveredServer(string server,string database, DatabaseType databaseType /// /// Optional - when provided returns the instead of opening a new one /// - public DbConnection GetConnection(IManagedTransaction transaction = null) => transaction != null ? transaction.Connection : Helper.GetConnection(Builder); + public DbConnection GetConnection(IManagedTransaction? transaction = null) => transaction != null ? transaction.Connection : Helper.GetConnection(Builder); /// public DbCommand GetCommand(string sql, IManagedConnection managedConnection) @@ -124,7 +124,7 @@ public DbCommand GetCommand(string sql, IManagedConnection managedConnection) /// Correctly typed connection for the . (See ) /// Optional - if provided the will be set to the /// - public DbCommand GetCommand(string sql, DbConnection con, IManagedTransaction transaction = null) + public DbCommand GetCommand(string sql, DbConnection con, IManagedTransaction? transaction = null) { var cmd = Helper.GetCommand(sql, con); @@ -242,7 +242,7 @@ public IEnumerable DiscoverDatabases() => Helper.ListDatabas /// /// Optional - if provided this method returns true (existence cannot be checked mid transaction). /// - public bool Exists(IManagedTransaction transaction = null) + public bool Exists(IManagedTransaction? transaction = null) { if (transaction != null) return true; @@ -357,7 +357,7 @@ public DiscoveredDatabase CreateDatabase(string newDatabaseName) /// /// /// - public IManagedConnection GetManagedConnection(IManagedTransaction transaction = null) => new ManagedConnection(this, transaction); + public IManagedConnection GetManagedConnection(IManagedTransaction? transaction = null) => new ManagedConnection(this, transaction); /// /// Returns helper for generating queries compatible with the DBMS (See ) e.g. TOP X, column qualifiers, what the parameter @@ -391,7 +391,7 @@ private bool Equals(DiscoveredServer other) /// /// /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/FAnsiSql/Discovery/DiscoveredServerHelper.cs b/FAnsiSql/Discovery/DiscoveredServerHelper.cs index 427eb19d..7861c121 100644 --- a/FAnsiSql/Discovery/DiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredServerHelper.cs @@ -33,7 +33,7 @@ public static void AddConnectionStringKeyword(DatabaseType databaseType, string } /// - public abstract DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null); + public abstract DbCommand GetCommand(string s, DbConnection con, DbTransaction? transaction = null); /// public abstract DbDataAdapter GetDataAdapter(DbCommand cmd); @@ -55,9 +55,9 @@ public DbConnectionStringBuilder GetConnectionStringBuilder(string connectionStr } /// - public DbConnectionStringBuilder GetConnectionStringBuilder(string server, string database, string username, string password) + public DbConnectionStringBuilder GetConnectionStringBuilder(string server, string? database, string username, string password) { - var builder = GetConnectionStringBuilderImpl(server,database,username,password); + var builder = GetConnectionStringBuilderImpl(server, database, username, password); EnforceKeywords(builder); return builder; } @@ -74,9 +74,9 @@ protected virtual void EnforceKeywords(DbConnectionStringBuilder builder) if (ConnectionStringKeywordAccumulators.TryGetValue(DatabaseType, out var accumulator)) accumulator.EnforceOptions(builder); } - protected abstract DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString, string database, string username, string password); - protected abstract DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString); + protected abstract DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString, string? database, string username, string password); + protected abstract DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString); protected abstract string ServerKeyName { get; } @@ -138,7 +138,7 @@ public ManagedTransaction BeginTransaction(DbConnectionStringBuilder builder) public DatabaseType DatabaseType { get; private set; } = databaseType; public abstract Dictionary DescribeServer(DbConnectionStringBuilder builder); - public bool RespondsWithinTime(DbConnectionStringBuilder builder, int timeoutInSeconds,out Exception exception) + public bool RespondsWithinTime(DbConnectionStringBuilder builder, int timeoutInSeconds, out Exception? exception) { try { diff --git a/FAnsiSql/Discovery/DiscoveredTable.cs b/FAnsiSql/Discovery/DiscoveredTable.cs index 04112ad8..493f0ef9 100644 --- a/FAnsiSql/Discovery/DiscoveredTable.cs +++ b/FAnsiSql/Discovery/DiscoveredTable.cs @@ -56,7 +56,7 @@ public class DiscoveredTable : IHasFullyQualifiedNameToo, IMightNotExist, IHasQu /// /// /// - public DiscoveredTable(DiscoveredDatabase database, string table, IQuerySyntaxHelper querySyntaxHelper, string schema = null, TableType tableType = TableType.Table) + public DiscoveredTable(DiscoveredDatabase database, string table, IQuerySyntaxHelper querySyntaxHelper, string? schema = null, TableType tableType = TableType.Table) { TableName = table; Helper = database.Helper.GetTableHelper(); @@ -75,7 +75,7 @@ public DiscoveredTable(DiscoveredDatabase database, string table, IQuerySyntaxHe /// Optional - if set the connection to list tables will be sent on the connection on which the current /// is open /// - public virtual bool Exists(IManagedTransaction transaction = null) + public virtual bool Exists(IManagedTransaction? transaction = null) { if (!Database.Exists()) return false; @@ -108,7 +108,7 @@ public virtual bool Exists(IManagedTransaction transaction = null) /// Optional - if set the connection to list tables will be sent on the connection on which the current /// is open /// - public DiscoveredColumn[] DiscoverColumns(IManagedTransaction managedTransaction=null) + public DiscoveredColumn[] DiscoverColumns(IManagedTransaction? managedTransaction=null) { using var connection = Database.Server.GetManagedConnection(managedTransaction); return Helper.DiscoverColumns(this, connection, Database.GetRuntimeName()); @@ -134,7 +134,7 @@ public DiscoveredColumn[] DiscoverColumns(IManagedTransaction managedTransaction /// Optional - if set the connection to list tables will be sent on the connection on which the current /// is open /// - public DiscoveredColumn DiscoverColumn(string specificColumnName,IManagedTransaction transaction=null) + public DiscoveredColumn DiscoverColumn(string specificColumnName,IManagedTransaction? transaction=null) { try { @@ -160,7 +160,7 @@ public DiscoveredColumn DiscoverColumn(string specificColumnName,IManagedTransac /// schema of the /// Optional - if set the connection to fetch the data will be sent on the connection on which the current is open /// - public DataTable GetDataTable(int topX = int.MaxValue,bool enforceTypesAndNullness = true, IManagedTransaction transaction = null) => GetDataTable(new DatabaseOperationArgs {TransactionIfAny = transaction},topX,enforceTypesAndNullness); + public DataTable GetDataTable(int topX = int.MaxValue,bool enforceTypesAndNullness = true, IManagedTransaction? transaction = null) => GetDataTable(new DatabaseOperationArgs {TransactionIfAny = transaction},topX,enforceTypesAndNullness); public DataTable GetDataTable(DatabaseOperationArgs args,int topX = int.MaxValue, bool enforceTypesAndNullness = true) { @@ -188,7 +188,7 @@ public virtual void Drop() Helper.DropTable(connection.Connection,this); } - public int GetRowCount(IManagedTransaction transaction = null) => GetRowCount(new DatabaseOperationArgs { TransactionIfAny = transaction}); + public int GetRowCount(IManagedTransaction? transaction = null) => GetRowCount(new DatabaseOperationArgs { TransactionIfAny = transaction}); /// /// Returns the estimated number of rows in the table. This may use a short cut e.g. consulting sys.partitions in Sql @@ -203,7 +203,7 @@ public virtual void Drop() /// /// Optional - if set the query will be sent on the connection on which the current is open /// - public bool IsEmpty(IManagedTransaction transaction = null) => IsEmpty(new DatabaseOperationArgs {TransactionIfAny = transaction}); + public bool IsEmpty(IManagedTransaction? transaction = null) => IsEmpty(new DatabaseOperationArgs {TransactionIfAny = transaction}); /// /// Returns true if there are no rows in the table @@ -269,7 +269,7 @@ public void DropColumn(DiscoveredColumn column) /// /// Optional - records inserted should form part of the supplied ongoing transaction /// - public IBulkCopy BeginBulkInsert(IManagedTransaction transaction = null) => BeginBulkInsert(CultureInfo.CurrentCulture, transaction); + public IBulkCopy BeginBulkInsert(IManagedTransaction? transaction = null) => BeginBulkInsert(CultureInfo.CurrentCulture, transaction); /// /// Creates a new object for bulk inserting records into the table. You should use a using block since is . @@ -278,7 +278,7 @@ public void DropColumn(DiscoveredColumn column) /// /// Optional - records inserted should form part of the supplied ongoing transaction /// - public IBulkCopy BeginBulkInsert(CultureInfo culture,IManagedTransaction transaction = null) + public IBulkCopy BeginBulkInsert(CultureInfo culture,IManagedTransaction? transaction = null) { Database.Server.EnableAsync(); var connection = Database.Server.GetManagedConnection(transaction); @@ -325,7 +325,7 @@ public void MakeDistinct(DatabaseOperationArgs args) /// Optional, If provided the SQL generated will be adjusted to create the alternate table instead (which could include going cross server type e.g. MySql to Sql Server) /// When using this parameter the table must not exist yet, use destinationDiscoveredDatabase.ExpectTable("MyYetToExistTable") /// - public string ScriptTableCreation(bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable toCreateTable = null) => Helper.ScriptTableCreation(this, dropPrimaryKeys, dropNullability, convertIdentityToInt, toCreateTable); + public string ScriptTableCreation(bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable? toCreateTable = null) => Helper.ScriptTableCreation(this, dropPrimaryKeys, dropNullability, convertIdentityToInt, toCreateTable); /// /// Issues a database command to rename the table on the database server. @@ -364,7 +364,7 @@ public void CreatePrimaryKey(int timeoutInSeconds, params DiscoveredColumn[] dis /// Token for cancelling the command mid execution (leave null if not needed) /// The number of seconds to wait for the operation to complete /// Columns that should become part of the primary key - public void CreatePrimaryKey(IManagedTransaction transaction ,CancellationToken token, int timeoutInSeconds, params DiscoveredColumn[] discoverColumns) + public void CreatePrimaryKey(IManagedTransaction? transaction, CancellationToken token, int timeoutInSeconds, params DiscoveredColumn[] discoverColumns) { Helper.CreatePrimaryKey(new DatabaseOperationArgs{ TransactionIfAny = transaction, @@ -385,7 +385,7 @@ public void CreatePrimaryKey(DatabaseOperationArgs args, params DiscoveredColumn /// /// /// - public int Insert(Dictionary toInsert, IManagedTransaction transaction = null) => Insert(toInsert, null, transaction); + public int Insert(Dictionary toInsert, IManagedTransaction? transaction = null) => Insert(toInsert, null, transaction); /// /// Inserts the values specified into the database table and returns the last autonum identity generated (or 0 if none present) @@ -394,7 +394,7 @@ public void CreatePrimaryKey(DatabaseOperationArgs args, params DiscoveredColumn /// /// /// - public int Insert(Dictionary toInsert, CultureInfo culture, IManagedTransaction transaction=null) + public int Insert(Dictionary toInsert, CultureInfo? culture, IManagedTransaction? transaction=null) { var syntaxHelper = GetQuerySyntaxHelper(); var server = Database.Server; @@ -421,7 +421,7 @@ public int Insert(Dictionary toInsert, CultureInfo cult /// /// ongoing transaction this insert should be part of /// - public int Insert(Dictionary toInsert, IManagedTransaction transaction = null) => Insert(toInsert,null, transaction); + public int Insert(Dictionary toInsert, IManagedTransaction? transaction = null) => Insert(toInsert,null, transaction); /// /// Overload which will discover the columns by name for you. @@ -430,7 +430,7 @@ public int Insert(Dictionary toInsert, CultureInfo cult /// /// ongoing transaction this insert should be part of /// - public int Insert(Dictionary toInsert, CultureInfo culture, IManagedTransaction transaction = null) + public int Insert(Dictionary toInsert, CultureInfo? culture, IManagedTransaction? transaction = null) { var cols = DiscoverColumns(transaction); @@ -453,14 +453,14 @@ public int Insert(Dictionary toInsert, CultureInfo culture, IMan /// /// See /// - public DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => Database.Server.Helper.GetCommand(s, con, transaction); + public DbCommand GetCommand(string s, DbConnection con, DbTransaction? transaction = null) => Database.Server.Helper.GetCommand(s, con, transaction); /// /// Returns all foreign keys where this table is the parent table (i.e. the primary key table). /// /// /// - public DiscoveredRelationship[] DiscoverRelationships(IManagedTransaction transaction = null) + public DiscoveredRelationship[] DiscoverRelationships(IManagedTransaction? transaction = null) { using var connection = Database.Server.GetManagedConnection(transaction); return Helper.DiscoverRelationships(this, connection.Connection,transaction); @@ -471,7 +471,7 @@ public DiscoveredRelationship[] DiscoverRelationships(IManagedTransaction transa /// /// /// - public bool Equals(DiscoveredTable other) + public bool Equals(DiscoveredTable? other) { if (other is null) return false; @@ -490,7 +490,7 @@ private string GetSchemaWithDefaultForNull() => /// /// /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; @@ -514,7 +514,7 @@ public override int GetHashCode() } } - public DiscoveredRelationship AddForeignKey(DiscoveredColumn foreignKey, DiscoveredColumn primaryKey, bool cascadeDeletes,string constraintName = null, DatabaseOperationArgs args = null) => AddForeignKey(new Dictionary{{foreignKey,primaryKey}},cascadeDeletes,constraintName,args); + public DiscoveredRelationship AddForeignKey(DiscoveredColumn foreignKey, DiscoveredColumn primaryKey, bool cascadeDeletes,string? constraintName = null, DatabaseOperationArgs? args = null) => AddForeignKey(new Dictionary{{foreignKey,primaryKey}},cascadeDeletes,constraintName,args); /// /// @@ -527,6 +527,6 @@ public override int GetHashCode() /// Options for timeout, transaction etc /// public DiscoveredRelationship AddForeignKey(Dictionary foreignKeyPairs, - bool cascadeDeletes,string constraintName = null, DatabaseOperationArgs args = null) => + bool cascadeDeletes,string? constraintName = null, DatabaseOperationArgs? args = null) => Helper.AddForeignKey(args??new DatabaseOperationArgs(),foreignKeyPairs, cascadeDeletes,constraintName); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/DiscoveredTableHelper.cs b/FAnsiSql/Discovery/DiscoveredTableHelper.cs index 737ea0d5..cfe65ffa 100644 --- a/FAnsiSql/Discovery/DiscoveredTableHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredTableHelper.cs @@ -70,7 +70,7 @@ public virtual void TruncateTable(DiscoveredTable discoveredTable) } /// - public string ScriptTableCreation(DiscoveredTable table, bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable toCreateTable = null) + public string ScriptTableCreation(DiscoveredTable table, bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable? toCreateTable = null) { var columns = new List(); @@ -88,16 +88,16 @@ public string ScriptTableCreation(DiscoveredTable table, bool dropPrimaryKeys, b if (isToDifferentDatabaseType) { var fromtt = table.Database.Server.GetQuerySyntaxHelper().TypeTranslater; - var tott = toCreateTable.Database.Server.GetQuerySyntaxHelper().TypeTranslater; + var tott = toCreateTable?.Database.Server.GetQuerySyntaxHelper().TypeTranslater ?? throw new InvalidOperationException($"Unable to retrieve type translator for {toCreateTable}"); sqlType = fromtt.TranslateSQLDBType(c.DataType.SQLType, tott); } - var colRequest = new DatabaseColumnRequest(c.GetRuntimeName(),sqlType , c.AllowNulls || dropNullability) - { - IsPrimaryKey = c.IsPrimaryKey && !dropPrimaryKeys, - IsAutoIncrement = c.IsAutoIncrement && !convertIdentityToInt - }; + var colRequest = new DatabaseColumnRequest(c.GetRuntimeName(), sqlType, c.AllowNulls || dropNullability) + { + IsPrimaryKey = c.IsPrimaryKey && !dropPrimaryKeys, + IsAutoIncrement = c.IsAutoIncrement && !convertIdentityToInt + }; colRequest.AllowNulls = colRequest.AllowNulls && !colRequest.IsAutoIncrement; @@ -149,7 +149,7 @@ public virtual void CreatePrimaryKey(DatabaseOperationArgs args, DiscoveredTable } } - public virtual int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, IManagedTransaction transaction=null) + public virtual int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, IManagedTransaction? transaction=null) { cmd.CommandText += ";SELECT @@IDENTITY"; @@ -161,7 +161,7 @@ public virtual int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTabl return Convert.ToInt32(result); } - public abstract DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table,DbConnection connection, IManagedTransaction transaction = null); + public abstract DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table,DbConnection connection, IManagedTransaction? transaction = null); public virtual void FillDataTableWithTopX(DatabaseOperationArgs args,DiscoveredTable table, int topX, DataTable dt) { @@ -174,7 +174,7 @@ public virtual void FillDataTableWithTopX(DatabaseOperationArgs args,DiscoveredT } /// - public virtual DiscoveredRelationship AddForeignKey(DatabaseOperationArgs args,Dictionary foreignKeyPairs, bool cascadeDeletes, string constraintName = null) + public virtual DiscoveredRelationship AddForeignKey(DatabaseOperationArgs args,Dictionary foreignKeyPairs, bool cascadeDeletes, string? constraintName = null) { var foreignTables = foreignKeyPairs.Select(static c => c.Key.Table).Distinct().ToArray(); var primaryTables= foreignKeyPairs.Select(static c => c.Value.Table).Distinct().ToArray(); diff --git a/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs b/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs index ecec8443..0f35d3cc 100644 --- a/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs +++ b/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs @@ -12,10 +12,10 @@ namespace FAnsi.Discovery; public sealed class DiscoveredTableValuedFunction(DiscoveredDatabase database, string functionName, IQuerySyntaxHelper querySyntaxHelper, - string schema = null) : DiscoveredTable(database, functionName, querySyntaxHelper, + string? schema = null) : DiscoveredTable(database, functionName, querySyntaxHelper, schema, TableType.TableValuedFunction) { - public override bool Exists(IManagedTransaction transaction = null) + public override bool Exists(IManagedTransaction? transaction = null) { return Database.DiscoverTableValuedFunctions(transaction).Any(f => f.GetRuntimeName().Equals(GetRuntimeName())); } @@ -39,7 +39,7 @@ public override void Drop() Helper.DropFunction(connection.Connection, this); } - public IEnumerable DiscoverParameters(ManagedTransaction transaction = null) + public IEnumerable DiscoverParameters(ManagedTransaction? transaction = null) { using var connection = Database.Server.GetManagedConnection(transaction); return Helper.DiscoverTableValuedFunctionParameters(connection.Connection, this, connection.Transaction); diff --git a/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs b/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs index 24939e4c..8e408e3a 100644 --- a/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs @@ -15,8 +15,8 @@ namespace FAnsi.Discovery; public interface IDiscoveredDatabaseHelper { - IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction transaction = null); - IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, DbTransaction transaction = null); + IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction? transaction = null); + IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, DbTransaction? transaction = null); DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStringBuilder builder, string database); @@ -27,7 +27,8 @@ public interface IDiscoveredDatabaseHelper DiscoveredTable CreateTable(CreateTableArgs args); - string GetCreateTableSql(DiscoveredDatabase database, string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete,string schema = null); + string GetCreateTableSql(DiscoveredDatabase database, string tableName, DatabaseColumnRequest[] columns, + Dictionary? foreignKeyPairs, bool cascadeDelete, string? schema = null); /// /// Generates foreign key creation SQL such that it can be slotted into either a CREATE TABLE statement OR a ALTER TABLE statement @@ -43,7 +44,7 @@ public interface IDiscoveredDatabaseHelper /// The name of the new constraint to create or null to use default /// string GetForeignKeyConstraintSql(string foreignTable, IQuerySyntaxHelper syntaxHelper, - Dictionary foreignKeyPairs, bool cascadeDelete, string constraintName = null); + Dictionary foreignKeyPairs, bool cascadeDelete, string? constraintName = null); DirectoryInfo Detach(DiscoveredDatabase database); void CreateBackup(DiscoveredDatabase discoveredDatabase, string backupName); diff --git a/FAnsiSql/Discovery/IDiscoveredServerHelper.cs b/FAnsiSql/Discovery/IDiscoveredServerHelper.cs index ece65f91..d2f81ce4 100644 --- a/FAnsiSql/Discovery/IDiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredServerHelper.cs @@ -14,7 +14,8 @@ namespace FAnsi.Discovery; public interface IDiscoveredServerHelper { /// - DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null); + DbCommand GetCommand(string s, DbConnection con, DbTransaction? transaction = null); + DbDataAdapter GetDataAdapter(DbCommand cmd); DbCommandBuilder GetCommandBuilder(DbCommand cmd); DbParameter GetParameter(string parameterName); @@ -32,7 +33,7 @@ public interface IDiscoveredServerHelper /// Optional username to set in connection string (otherwise integrated security will be used - if supported) /// Optional password to set in connection string (otherwise integrated security will be used - if supported) /// - DbConnectionStringBuilder GetConnectionStringBuilder(string server, string database, string username, string password); + DbConnectionStringBuilder GetConnectionStringBuilder(string server, string? database, string username, string password); string GetServerName(DbConnectionStringBuilder builder); DbConnectionStringBuilder ChangeServer(DbConnectionStringBuilder builder, string newServer); @@ -53,7 +54,7 @@ public interface IDiscoveredServerHelper ManagedTransaction BeginTransaction(DbConnectionStringBuilder builder); DatabaseType DatabaseType { get; } Dictionary DescribeServer(DbConnectionStringBuilder builder); - bool RespondsWithinTime(DbConnectionStringBuilder builder, int timeoutInSeconds, out Exception exception); + bool RespondsWithinTime(DbConnectionStringBuilder builder, int timeoutInSeconds, out Exception? exception); string GetExplicitUsernameIfAny(DbConnectionStringBuilder builder); string GetExplicitPasswordIfAny(DbConnectionStringBuilder builder); diff --git a/FAnsiSql/Discovery/IDiscoveredTableHelper.cs b/FAnsiSql/Discovery/IDiscoveredTableHelper.cs index f4c96679..52e8a2bf 100644 --- a/FAnsiSql/Discovery/IDiscoveredTableHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredTableHelper.cs @@ -37,12 +37,12 @@ public interface IDiscoveredTableHelper void MakeDistinct(DatabaseOperationArgs args,DiscoveredTable discoveredTable); /// - string ScriptTableCreation(DiscoveredTable constraints, bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable toCreateTable = null); + string ScriptTableCreation(DiscoveredTable constraints, bool dropPrimaryKeys, bool dropNullability, bool convertIdentityToInt, DiscoveredTable? toCreateTable = null); bool IsEmpty(DatabaseOperationArgs args, DiscoveredTable discoveredTable); void RenameTable(DiscoveredTable discoveredTable, string newName, IManagedConnection connection); void CreatePrimaryKey(DatabaseOperationArgs args, DiscoveredTable columns, DiscoveredColumn[] discoverColumns); - int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, IManagedTransaction transaction=null); - DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable discoveredTable,DbConnection connection, IManagedTransaction transaction = null); + int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, IManagedTransaction? transaction=null); + DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable discoveredTable,DbConnection connection, IManagedTransaction? transaction = null); void FillDataTableWithTopX(DatabaseOperationArgs args,DiscoveredTable table, int topX, DataTable dt); @@ -58,5 +58,5 @@ public interface IDiscoveredTableHelper /// The name to give the foreign key constraint created, if null then a default name will be picked e.g. FK_Tbl1_Tbl2 /// Options for timeout, transaction etc /// - DiscoveredRelationship AddForeignKey(DatabaseOperationArgs args, Dictionary foreignKeyPairs, bool cascadeDeletes,string constraintName =null); + DiscoveredRelationship AddForeignKey(DatabaseOperationArgs args, Dictionary foreignKeyPairs, bool cascadeDeletes,string? constraintName =null); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/IMightNotExist.cs b/FAnsiSql/Discovery/IMightNotExist.cs index fc5368d6..f7bd64ba 100644 --- a/FAnsiSql/Discovery/IMightNotExist.cs +++ b/FAnsiSql/Discovery/IMightNotExist.cs @@ -15,5 +15,5 @@ public interface IMightNotExist /// /// /// - bool Exists(IManagedTransaction transaction = null); + bool Exists(IManagedTransaction? transaction = null); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs index 32669149..620af7cb 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs @@ -11,10 +11,10 @@ namespace FAnsi.Discovery.QuerySyntax.Aggregation; public sealed class AggregateCustomLineCollection { public List Lines { get; set; } - public IQueryAxis Axis { get; set; } + public IQueryAxis? Axis { get; set; } public IQuerySyntaxHelper SyntaxHelper { get; } - public AggregateCustomLineCollection(List queryLines, IQueryAxis axisIfAny, IQuerySyntaxHelper querySyntaxHelper) + public AggregateCustomLineCollection(List queryLines, IQueryAxis? axisIfAny, IQuerySyntaxHelper querySyntaxHelper) { Lines = queryLines; Axis = axisIfAny; diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs index 4f5b1651..fa2de438 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs @@ -6,7 +6,7 @@ namespace FAnsi.Discovery.QuerySyntax.Aggregation; public abstract class AggregateHelper:IAggregateHelper { - public string BuildAggregate(List queryLines, IQueryAxis axisIfAny) + public string BuildAggregate(List queryLines, IQueryAxis? axisIfAny) { var lines = new AggregateCustomLineCollection(queryLines, axisIfAny, GetQuerySyntaxHelper()); @@ -70,7 +70,7 @@ protected void WrapAxisColumnWithDatePartFunction(AggregateCustomLineCollection var axisColumnEndedWithComma = query.AxisSelect.Text.EndsWith(','); query.AxisSelect.Text = - $"{GetDatePartOfColumn(query.Axis.AxisIncrement, axisColumnWithoutAlias)} AS {axisColumnAlias}{(axisColumnEndedWithComma ? "," : "")}"; + $"{GetDatePartOfColumn(query.Axis?.AxisIncrement ?? throw new InvalidOperationException("No axis in query"), axisColumnWithoutAlias)} AS {axisColumnAlias}{(axisColumnEndedWithComma ? "," : "")}"; var groupByEndedWithComma = axisGroupBy.Text.EndsWith(','); axisGroupBy.Text = GetDatePartOfColumn(query.Axis.AxisIncrement, axisColumnWithoutAlias) + (groupByEndedWithComma ? "," : ""); diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs index 25738c45..7a9e047a 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs @@ -19,5 +19,5 @@ public interface IAggregateHelper /// /// /// - string BuildAggregate(List queryLines, IQueryAxis axisIfAny); + string BuildAggregate(List queryLines, IQueryAxis? axisIfAny); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs index f181f425..1cc82767 100644 --- a/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs @@ -31,7 +31,7 @@ public interface IQuerySyntaxHelper /// /// Function to convert the to a string e.g. c.ColumnName if DataColumn /// - Dictionary GetParameterNamesFor(T[] columns, Func toStringFunc); + Dictionary GetParameterNamesFor(T[] columns, Func toStringFunc) where T : notnull; IAggregateHelper AggregateHelper { get; } IUpdateHelper UpdateHelper { get; set; } @@ -50,6 +50,7 @@ public interface IQuerySyntaxHelper /// Separator between table and column names (and database, schema etc). Usually "." /// string DatabaseTableSeparator {get; } + /// /// Characters which are not permitted in column names by FAnsi /// @@ -59,9 +60,9 @@ public interface IQuerySyntaxHelper string GetRuntimeName(string s); - bool TryGetRuntimeName(string s, out string name); + bool TryGetRuntimeName(string s, out string? name); - DatabaseType DatabaseType {get;} + DatabaseType DatabaseType { get; } /// /// True if the DBMS supports SQL declared parameters (e.g. "DECLARE @bob varchar(10)") whose values can be changed in SQL. False if the only way to @@ -76,10 +77,10 @@ public interface IQuerySyntaxHelper /// /// /// - string EnsureWrapped(string databaseOrTableName); + string? EnsureWrapped(string? databaseOrTableName); - string EnsureFullyQualified(string databaseName,string schemaName, string tableName); - string EnsureFullyQualified(string databaseName, string schemaName,string tableName, string columnName, bool isTableValuedFunction = false); + string EnsureFullyQualified(string databaseName, string? schemaName, string tableName); + string EnsureFullyQualified(string databaseName, string? schemaName, string tableName, string columnName, bool isTableValuedFunction = false); /// /// Returns the given escaped e.g. doubling up single quotes. Does not add any wrapping. @@ -112,7 +113,7 @@ public interface IQuerySyntaxHelper int MaximumColumnLength { get; } - bool SplitLineIntoSelectSQLAndAlias(string lineToSplit, out string selectSQL, out string alias); + bool SplitLineIntoSelectSQLAndAlias(string lineToSplit, out string selectSQL, out string? alias); string GetScalarFunctionSql(MandatoryScalarFunctions function); string GetSensibleEntityNameFromString(string potentiallyDodgyName); @@ -178,7 +179,7 @@ public interface IQuerySyntaxHelper /// Throws if the supplied name is invalid (because it is too long or contains unsupported characters) /// /// - void ValidateDatabaseName(string database); + void ValidateDatabaseName(string? database); /// /// Throws if the supplied name is invalid (because it is too long or contains unsupported characters) @@ -193,7 +194,7 @@ public interface IQuerySyntaxHelper /// /// Returns false if the supplied name is invalid (because it is too long or contains unsupported characters) /// - bool IsValidDatabaseName(string databaseName, out string reason); + bool IsValidDatabaseName(string databaseName, out string? reason); /// /// Returns false if the supplied name is invalid (because it is too long or contains unsupported characters) diff --git a/FAnsiSql/Discovery/QuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntaxHelper.cs index 6aa4ad68..223fbf21 100644 --- a/FAnsiSql/Discovery/QuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntaxHelper.cs @@ -149,7 +149,7 @@ public virtual string GetRuntimeName(string s) /// The final runtime name unescaped e.g. "Fi`sh" protected virtual string UnescapeWrappedNameBody(string name) => name; - public virtual bool TryGetRuntimeName(string s,out string name) + public virtual bool TryGetRuntimeName(string s, out string? name) { try { @@ -165,7 +165,7 @@ public virtual bool TryGetRuntimeName(string s,out string name) public abstract bool SupportsEmbeddedParameters(); - public string EnsureWrapped(string databaseOrTableName) + public string? EnsureWrapped(string? databaseOrTableName) { if (string.IsNullOrWhiteSpace(databaseOrTableName)) return databaseOrTableName; @@ -178,15 +178,12 @@ public string EnsureWrapped(string databaseOrTableName) public abstract string EnsureWrappedImpl(string databaseOrTableName); - public abstract string EnsureFullyQualified(string databaseName, string schema, string tableName); + public abstract string EnsureFullyQualified(string databaseName, string? schema, string tableName); - public virtual string EnsureFullyQualified(string databaseName, string schema, string tableName, string columnName, bool isTableValuedFunction = false) - { - if (isTableValuedFunction) - return $"{GetRuntimeName(tableName)}.{GetRuntimeName(columnName)}";//table valued functions do not support database name being in the column level selection list area of sql queries - - return $"{EnsureFullyQualified(databaseName, schema, tableName)}.{EnsureWrapped(GetRuntimeName(columnName))}"; - } + public virtual string EnsureFullyQualified(string databaseName, string? schema, string tableName, string columnName, bool isTableValuedFunction = false) => + isTableValuedFunction ? $"{GetRuntimeName(tableName)}.{GetRuntimeName(columnName)}" + : //table valued functions do not support database name being in the column level selection list area of sql queries + $"{EnsureFullyQualified(databaseName, schema, tableName)}.{EnsureWrapped(GetRuntimeName(columnName))}"; public virtual string Escape(string sql) => string.IsNullOrWhiteSpace(sql) ? sql : sql.Replace("'", "''"); public abstract TopXResponse HowDoWeAchieveTopX(int x); @@ -204,7 +201,7 @@ public virtual string EnsureFullyQualified(string databaseName, string schema, s /// /// /// - public virtual bool SplitLineIntoSelectSQLAndAlias(string lineToSplit, out string selectSQL, out string alias) + public virtual bool SplitLineIntoSelectSQLAndAlias(string lineToSplit, out string selectSQL, out string? alias) { //Ths line is expected to be some SELECT sql so remove trailing whitespace and commas etc lineToSplit = lineToSplit.TrimEnd(',', ' ', '\n', '\r'); @@ -332,15 +329,14 @@ public virtual bool IsTimeout(Exception exception) => public abstract string HowDoWeAchieveMd5(string selectSql); - - public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn, object value,CultureInfo culture) + public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn, object value, CultureInfo? culture) { try { culture ??= CultureInfo.InvariantCulture; - if(!factories.ContainsKey(culture)) - factories.Add(culture,new TypeDeciderFactory(culture)); + if (!factories.ContainsKey(culture)) + factories.Add(culture, new TypeDeciderFactory(culture)); var tt = TypeTranslater; p.DbType = tt.GetDbTypeForSQLDBType(discoveredColumn.DataType.SQLType); @@ -348,20 +344,18 @@ public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn if (IsBasicallyNull(value)) p.Value = DBNull.Value; - else - if (value is string strVal && factories[culture].IsSupported(cSharpType)) //if the input is a string and it's for a hard type e.g. TimeSpan + else if (value is string strVal && factories[culture].IsSupported(cSharpType)) //if the input is a string and it's for a hard type e.g. TimeSpan { var decider = factories[culture].Create(cSharpType); var o = decider.Parse(strVal); - if(o is DateTime d) o = FormatDateTimeForDbParameter(d); + if (o is DateTime d) o = FormatDateTimeForDbParameter(d); //Not all DBMS support DBParameter.Value = new TimeSpan(...); if (o is TimeSpan t) o = FormatTimespanForDbParameter(t); p.Value = o; - } else p.Value = value; @@ -374,9 +368,9 @@ public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn return p; } - public void ValidateDatabaseName(string databaseName) + public void ValidateDatabaseName(string? databaseName) { - if(!IsValidDatabaseName(databaseName,out var reason)) + if (!IsValidDatabaseName(databaseName, out var reason)) throw new RuntimeNameException(reason); } public void ValidateTableName(string tableName) @@ -390,7 +384,7 @@ public void ValidateColumnName(string columnName) throw new RuntimeNameException(reason); } - public bool IsValidDatabaseName(string databaseName,out string reason) + public bool IsValidDatabaseName(string? databaseName, out string? reason) { reason = ValidateName(databaseName, "Database", MaximumDatabaseLength); return string.IsNullOrWhiteSpace(reason); @@ -417,16 +411,16 @@ public bool IsValidColumnName(string columnName,out string reason) /// Type of object being validated e.g. "Database", "Table" etc /// /// - private string ValidateName(string candidate, string objectType, int maximumLengthAllowed) + private string? ValidateName(string? candidate, string objectType, int maximumLengthAllowed) { - if(string.IsNullOrWhiteSpace(candidate)) + if (string.IsNullOrWhiteSpace(candidate)) return string.Format(FAnsiStrings.QuerySyntaxHelper_ValidateName__0__name_cannot_be_blank, objectType); - if(candidate.Length > maximumLengthAllowed) + if (candidate.Length > maximumLengthAllowed) return string.Format(FAnsiStrings.QuerySyntaxHelper_ValidateName__0__name___1___is_too_long_for_the_DBMS___2__supports_maximum_length_of__3__, objectType, candidate[..maximumLengthAllowed], DatabaseType, maximumLengthAllowed); - if(candidate.IndexOfAny(IllegalNameChars) != -1) + if (candidate.IndexOfAny(IllegalNameChars) != -1) return string.Format( FAnsiStrings.QuerySyntaxHelper_ValidateName__0__name___1___contained_unsupported__by_FAnsi__characters___Unsupported_characters_are__2_, objectType, candidate, new string(IllegalNameChars)); @@ -435,8 +429,7 @@ private string ValidateName(string candidate, string objectType, int maximumLeng } - - public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn, object value) => GetParameter(p,discoveredColumn,value,null); + public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn, object value) => GetParameter(p, discoveredColumn, value, null); /// /// @@ -466,7 +459,7 @@ protected bool Equals(QuerySyntaxHelper other) return GetType() == other.GetType(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; @@ -479,7 +472,7 @@ public override bool Equals(object obj) #endregion - public Dictionary GetParameterNamesFor(T[] columns, Func toStringFunc) + public Dictionary GetParameterNamesFor(T[] columns, Func toStringFunc) where T : notnull { var toReturn = new Dictionary(); diff --git a/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs b/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs index 65b23691..05aebc7e 100644 --- a/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs +++ b/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs @@ -12,7 +12,7 @@ namespace FAnsi.Discovery.TableCreation; /// /// Create a table with the given name. Set your columns in /// -public sealed class CreateTableArgs(DiscoveredDatabase database, string tableName, string schema) +public sealed class CreateTableArgs(DiscoveredDatabase database, string tableName, string? schema) { /// /// The destination database in which to create the table @@ -88,8 +88,9 @@ public sealed class CreateTableArgs(DiscoveredDatabase database, string tableNam /// /// Create a table with the given name. Set your columns in /// - public CreateTableArgs(DiscoveredDatabase database,string tableName,string schema,Dictionary foreignKeyPairs,bool cascadeDelete) - :this(database,tableName,schema) + public CreateTableArgs(DiscoveredDatabase database, string tableName, string? schema, + Dictionary foreignKeyPairs, bool cascadeDelete) + : this(database, tableName, schema) { ForeignKeyPairs = foreignKeyPairs; CascadeDelete = cascadeDelete; @@ -99,8 +100,8 @@ public CreateTableArgs(DiscoveredDatabase database,string tableName,string schem /// Create a table with the given name based on the columns and data in the provided . If you want to override the /// data type of a given column set /// - public CreateTableArgs(DiscoveredDatabase database, string tableName, string schema,DataTable dataTable, bool createEmpty) - :this(database,tableName,schema) + public CreateTableArgs(DiscoveredDatabase database, string tableName, string? schema, DataTable dataTable, bool createEmpty) + : this(database, tableName, schema) { DataTable = dataTable; CreateEmpty = createEmpty; diff --git a/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs index 064c7c1b..46b294ff 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs @@ -246,7 +246,7 @@ ORDER BY return part1 + part2; } - private string GetPivotPart1(AggregateCustomLineCollection query, out string pivotAlias,out string countAlias, out string axisColumnAlias) + private string GetPivotPart1(AggregateCustomLineCollection query, out string pivotAlias, out string countAlias, out string? axisColumnAlias) { var syntaxHelper = query.SyntaxHelper; @@ -267,7 +267,7 @@ private string GetPivotPart1(AggregateCustomLineCollection query, out string piv //if there is an axis we don't want to pivot on values that are outside that axis restriction. if(query.Axis != null) - WrapAxisColumnWithDatePartFunction(query,axisColumnAlias); + WrapAxisColumnWithDatePartFunction(query, axisColumnAlias); else { axisColumnAlias = null; diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs index f6a9ff58..ce2609f1 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs @@ -19,12 +19,13 @@ public sealed partial class MicrosoftSQLBulkCopy : BulkCopy private static readonly Regex ColumnLevelComplaint = ColumnLevelComplaintRe(); - public MicrosoftSQLBulkCopy(DiscoveredTable targetTable, IManagedConnection connection,CultureInfo culture): base(targetTable, connection,culture) + public MicrosoftSQLBulkCopy(DiscoveredTable targetTable, IManagedConnection connection, CultureInfo culture) : base(targetTable, connection, + culture) { - var options=SqlBulkCopyOptions.KeepIdentity|SqlBulkCopyOptions.TableLock; + var options = SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.TableLock; if (connection.Transaction == null) options |= SqlBulkCopyOptions.UseInternalTransaction; - _bulkCopy = new SqlBulkCopy((SqlConnection)connection.Connection, options, (SqlTransaction)connection.Transaction) + _bulkCopy = new SqlBulkCopy((SqlConnection)connection.Connection, options, (SqlTransaction?)connection.Transaction) { BulkCopyTimeout = 50000, DestinationTableName = targetTable.GetFullyQualifiedName() @@ -125,9 +126,9 @@ private Exception AttemptLineByLineInsert(Exception e, SqlBulkCopy insert, DataT } catch (Exception exception) { - if (BcpColIdToString(investigationOneLineAtATime,exception as SqlException,out var result, out var badMapping)) + if (BcpColIdToString(investigationOneLineAtATime, exception as SqlException, out var result, out var badMapping)) { - if (!dt.Columns.Contains(badMapping.SourceColumn)) + if (badMapping is null || !dt.Columns.Contains(badMapping.SourceColumn)) return new Exception( string.Format( SR @@ -137,14 +138,14 @@ private Exception AttemptLineByLineInsert(Exception e, SqlBulkCopy insert, DataT var sourceValue = dr[badMapping.SourceColumn]; var destColumn = TargetTableColumns.SingleOrDefault(c =>c.GetRuntimeName().Equals(badMapping.DestinationColumn)); - if(destColumn != null) + if (destColumn != null) return new FileLoadException( string.Format(SR.MicrosoftSQLBulkCopy_AttemptLineByLineInsert_BulkInsert_failed_on_data_row__0__the_complaint_was_about_source_column____1____which_had_value____2____destination_data_type_was____3____4__5_, line, badMapping.SourceColumn, sourceValue, destColumn.DataType, Environment.NewLine, result), exception); return new Exception(string.Format(SR.MicrosoftSQLBulkCopy_AttemptLineByLineInsert_BulkInsert_failed_on_data_row__0___1_, line, result), e); } - return new FileLoadException( + return new FileLoadException( string.Format(SR.MicrosoftSQLBulkCopy_AttemptLineByLineInsert_Second_Pass_Exception__Failed_to_load_data_row__0__the_following_values_were_rejected_by_the_database___1__2__3_, line, Environment.NewLine, string.Join(Environment.NewLine,dr.ItemArray), firstPass), exception); } @@ -165,7 +166,7 @@ private Exception AttemptLineByLineInsert(Exception e, SqlBulkCopy insert, DataT /// /// /// - private bool BcpColIdToString(SqlBulkCopy insert, SqlException ex, out string newMessage, out SqlBulkCopyColumnMapping badMapping) + private bool BcpColIdToString(SqlBulkCopy insert, SqlException? ex, out string? newMessage, out SqlBulkCopyColumnMapping? badMapping) { var match = ColumnLevelComplaint.Match(ex?.Message ?? ""); if (ex == null || !match.Success) @@ -176,18 +177,18 @@ private bool BcpColIdToString(SqlBulkCopy insert, SqlException ex, out string ne } //it counts from 1 not 0. Also it isn't an index into insert.ColumnMappings. It's an index into a private field! - var columnItHates = Convert.ToInt32(match.Groups[1].Value) -1; + var columnItHates = Convert.ToInt32(match.Groups[1].Value) - 1; try { var fi = typeof(SqlBulkCopy).GetField("_sortedColumnMappings", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new NullReferenceException(); var sortedColumns = fi.GetValue(insert); - var items = (object[])sortedColumns?.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(sortedColumns) ?? throw new NullReferenceException(); + var items = (object[])(sortedColumns?.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(sortedColumns) ?? throw new NullReferenceException()); var itemData = items[columnItHates].GetType().GetField("_metadata", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new NullReferenceException(); var metadata = itemData.GetValue(items[columnItHates]) ?? throw new NullReferenceException(); - var destinationColumn = (string)metadata.GetType().GetField("column", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(metadata) ?? throw new NullReferenceException(); + var destinationColumn = (string?)metadata.GetType().GetField("column", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(metadata) ?? throw new NullReferenceException(); var length = metadata.GetType().GetField("length", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(metadata); diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs index d47ca2c0..1a0cb5ad 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs @@ -19,7 +19,7 @@ public sealed class MicrosoftSQLDatabaseHelper: DiscoveredDatabaseHelper /// public static bool SetSingleUserWhenDroppingDatabases { get; set; } = true; - public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction transaction = null) + public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction? transaction = null) { if (connection.State == ConnectionState.Closed) throw new InvalidOperationException("Expected connection to be open"); @@ -55,7 +55,7 @@ public override IEnumerable ListTables(DiscoveredDatabase paren return tables.ToArray(); } - public override IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, DbTransaction transaction = null) + public override IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, DbTransaction? transaction = null) { var functionsToReturn = new List(); diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs index 4981093b..d86b3348 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs @@ -23,7 +23,7 @@ private MicrosoftSQLServerHelper() : base(DatabaseType.MicrosoftSQLServer) protected override string ConnectionTimeoutKeyName => "Connect Timeout"; #region Up Typing - public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => new SqlCommand(s, (SqlConnection)con, transaction as SqlTransaction); + public override DbCommand GetCommand(string s, DbConnection con, DbTransaction? transaction = null) => new SqlCommand(s, (SqlConnection)con, transaction as SqlTransaction); public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new SqlDataAdapter((SqlCommand) cmd); diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs index 3b508fa5..c7b9c836 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs @@ -184,7 +184,7 @@ public override void CreatePrimaryKey(DatabaseOperationArgs args, DiscoveredTabl base.CreatePrimaryKey(args,table, discoverColumns); } - public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table,DbConnection connection, IManagedTransaction transaction = null) + public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table,DbConnection connection, IManagedTransaction? transaction = null) { var toReturn = new Dictionary(); diff --git a/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs b/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs index ff23e0a5..a86f492a 100644 --- a/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs +++ b/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs @@ -17,20 +17,19 @@ namespace FAnsi.Implementations.MySql; public sealed partial class MySqlBulkCopy(DiscoveredTable targetTable, IManagedConnection connection, CultureInfo culture) : BulkCopy(targetTable, connection, culture) { - public static readonly int BulkInsertBatchTimeoutInSeconds = 0; public override int UploadImpl(DataTable dt) { - var ourTrans = Connection.Transaction==null?Connection.Connection.BeginTransaction(IsolationLevel.ReadUncommitted):null; + var ourTrans = Connection.Transaction == null ? Connection.Connection.BeginTransaction(IsolationLevel.ReadUncommitted) : null; var matchedColumns = GetMapping(dt.Columns.Cast()); var affected = 0; int maxPacket; - using (var packetQ = new MySqlCommand("select @@max_allowed_packet", (MySqlConnection)Connection.Connection,(MySqlTransaction)(Connection.Transaction ?? ourTrans))) + using (var packetQ = new MySqlCommand("select @@max_allowed_packet", (MySqlConnection)Connection.Connection, (MySqlTransaction?)(Connection.Transaction ?? ourTrans))) maxPacket = Convert.ToInt32(packetQ.ExecuteScalar()); using var cmd = new MySqlCommand("", (MySqlConnection) Connection.Connection, - (MySqlTransaction)(Connection.Transaction ?? ourTrans)); + (MySqlTransaction?)(Connection.Transaction ?? ourTrans)); if (BulkInsertBatchTimeoutInSeconds != 0) cmd.CommandTimeout = BulkInsertBatchTimeoutInSeconds; diff --git a/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs b/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs index c1aa27a0..41b96ce3 100644 --- a/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs @@ -13,7 +13,7 @@ namespace FAnsi.Implementations.MySql; public sealed class MySqlDatabaseHelper : DiscoveredDatabaseHelper { public override IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, - DbConnection connection, string database, DbTransaction transaction = null) => + DbConnection connection, string database, DbTransaction? transaction = null) => Enumerable.Empty(); public override DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStringBuilder builder, string database) => throw new NotImplementedException(); @@ -40,17 +40,11 @@ public override Dictionary DescribeDatabase(DbConnectionStringBu }; } - protected override string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) - { + protected override string GetCreateTableSqlLineForColumn(DatabaseColumnRequest col, string datatype, IQuerySyntaxHelper syntaxHelper) => //if it is not unicode then that's fine - if(col.TypeRequested == null || !col.TypeRequested.Unicode) - return base.GetCreateTableSqlLineForColumn(col, datatype, syntaxHelper); - - //MySql unicode is not a data type it's a character set/collation only - - return - $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} CHARACTER SET utf8mb4 {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} COLLATE {col.Collation ?? "utf8mb4_bin"} {(col.AllowNulls && !col.IsPrimaryKey ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; - } + col.TypeRequested?.Unicode != true ? base.GetCreateTableSqlLineForColumn(col, datatype, syntaxHelper) : + //MySql unicode is not a data type it's a character set/collation only + $"{syntaxHelper.EnsureWrapped(col.ColumnName)} {datatype} CHARACTER SET utf8mb4 {(col.Default != MandatoryScalarFunctions.None ? $"default {syntaxHelper.GetScalarFunctionSql(col.Default)}" : "")} COLLATE {col.Collation ?? "utf8mb4_bin"} {(col is { AllowNulls: true, IsPrimaryKey: false } ? " NULL" : " NOT NULL")} {(col.IsAutoIncrement ? syntaxHelper.GetAutoIncrementKeywordIfAny() : "")}"; public override DirectoryInfo Detach(DiscoveredDatabase database) => throw new NotImplementedException(); @@ -64,7 +58,7 @@ public override void CreateSchema(DiscoveredDatabase discoveredDatabase, string } - public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction transaction = null) + public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction? transaction = null) { if (connection.State == ConnectionState.Closed) throw new InvalidOperationException("Expected connection to be open"); diff --git a/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs b/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs index 368bf8dd..7becab9f 100644 --- a/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs @@ -26,7 +26,7 @@ private MySqlServerHelper() : base(DatabaseType.MySql) protected override string DatabaseKeyName => "Database"; #region Up Typing - public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => + public override DbCommand GetCommand(string s, DbConnection con, DbTransaction? transaction = null) => new MySqlCommand(s, con as MySqlConnection, transaction as MySqlTransaction); public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new MySqlDataAdapter(cmd as MySqlCommand ?? diff --git a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs index bb4c6f1c..2e22f6f5 100644 --- a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs @@ -129,7 +129,7 @@ public override IEnumerable DiscoverTableValuedFunctionPara public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable,IManagedConnection connection,CultureInfo culture) => new MySqlBulkCopy(discoveredTable, connection,culture); - public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table, DbConnection connection,IManagedTransaction transaction = null) + public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table, DbConnection connection,IManagedTransaction? transaction = null) { var toReturn = new Dictionary(); @@ -152,7 +152,7 @@ INNER JOIN u.REFERENCED_TABLE_NAME = @tbl """; - using (var cmd = new MySqlCommand(sql, (MySqlConnection) connection,(MySqlTransaction) transaction?.Transaction)) + using (var cmd = new MySqlCommand(sql, (MySqlConnection)connection, (MySqlTransaction?)transaction?.Transaction)) { var p = new MySqlParameter("@db", MySqlDbType.String) { diff --git a/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs b/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs index 6e89ba96..90f78318 100644 --- a/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs @@ -43,7 +43,7 @@ public override void CreateBackup(DiscoveredDatabase discoveredDatabase, string throw new NotImplementedException(); } - public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction transaction = null) + public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, string database, bool includeViews, DbTransaction? transaction = null) { var tables = new List(); @@ -77,7 +77,7 @@ public override IEnumerable ListTables(DiscoveredDatabase paren } public override IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, - DbConnection connection, string database, DbTransaction transaction = null) => + DbConnection connection, string database, DbTransaction? transaction = null) => Array.Empty(); public override DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStringBuilder builder, string database) => []; diff --git a/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs b/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs index 44d54f71..183a95cc 100644 --- a/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs @@ -22,7 +22,7 @@ private OracleServerHelper() : base(DatabaseType.Oracle) protected override string ConnectionTimeoutKeyName => "Connection Timeout"; #region Up Typing - public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => new OracleCommand(s, con as OracleConnection) {Transaction = transaction as OracleTransaction}; + public override DbCommand GetCommand(string s, DbConnection con, DbTransaction? transaction = null) => new OracleCommand(s, con as OracleConnection) {Transaction = transaction as OracleTransaction}; public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new OracleDataAdapter((OracleCommand) cmd); diff --git a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs index b0fd9501..24f12a45 100644 --- a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs @@ -63,7 +63,7 @@ FROM all_tab_cols "select table_name,column_name from ALL_TAB_IDENTITY_COLS WHERE table_name = :table_name AND owner =:owner", (OracleConnection) connection.Connection)) { - cmd.Transaction = (OracleTransaction) connection.Transaction; + cmd.Transaction = (OracleTransaction?)connection.Transaction; cmd.Parameters.Add(new OracleParameter("table_name", OracleDbType.Varchar2) { Value = tableName @@ -94,7 +94,7 @@ FROM all_tab_cols ORDER BY cols.table_name, cols.position """, (OracleConnection) connection.Connection)) { - cmd.Transaction = (OracleTransaction) connection.Transaction; + cmd.Transaction = (OracleTransaction?)connection.Transaction; cmd.Parameters.Add(new OracleParameter("table_name", OracleDbType.Varchar2) { Value = tableName @@ -183,7 +183,7 @@ public override IEnumerable DiscoverTableValuedFunctionPara public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable, IManagedConnection connection,CultureInfo culture) => new OracleBulkCopy(discoveredTable,connection,culture); - public override int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, IManagedTransaction transaction = null) + public override int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, IManagedTransaction? transaction = null) { var autoIncrement = discoveredTable.DiscoverColumns(transaction).SingleOrDefault(static c => c.IsAutoIncrement); @@ -208,7 +208,7 @@ public override int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTab } public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table, DbConnection connection, - IManagedTransaction transaction = null) + IManagedTransaction? transaction = null) { var toReturn = new Dictionary(); @@ -303,7 +303,7 @@ public override void FillDataTableWithTopX(DatabaseOperationArgs args,Discovered } - protected override string GetRenameTableSql(DiscoveredTable discoveredTable, string newName) + protected override string GetRenameTableSql(DiscoveredTable discoveredTable, string? newName) { newName = discoveredTable.GetQuerySyntaxHelper().EnsureWrapped(newName); return $@"alter table {discoveredTable.GetFullyQualifiedName()} rename to {newName}"; diff --git a/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs b/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs index 167e7d99..2bf0d2cc 100644 --- a/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs @@ -13,13 +13,13 @@ private PostgreSqlAggregateHelper(){} protected override string BuildAxisAggregate(AggregateCustomLineCollection query) { - var interval = query.Axis.AxisIncrement switch + var interval = query.Axis?.AxisIncrement switch { AxisIncrement.Day => "1 day", AxisIncrement.Month => "1 month", AxisIncrement.Year => "1 year", AxisIncrement.Quarter => "3 months", - _ => throw new ArgumentOutOfRangeException(nameof(query),$"Invalid AxisIncrement {query.Axis.AxisIncrement}") + _ => throw new ArgumentOutOfRangeException(nameof(query),$"Invalid AxisIncrement {query.Axis?.AxisIncrement}") }; var countAlias = query.CountSelect.GetAliasFromText(query.SyntaxHelper); diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs index b8df5b3b..00f29bee 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs @@ -15,7 +15,7 @@ public sealed class PostgreSqlDatabaseHelper : DiscoveredDatabaseHelper private PostgreSqlDatabaseHelper(){} public override IEnumerable ListTables(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, DbConnection connection, - string database, bool includeViews, DbTransaction transaction = null) + string database, bool includeViews, DbTransaction? transaction = null) { const string sqlTables = """ @@ -76,7 +76,7 @@ public override IEnumerable ListTables(DiscoveredDatabase paren } public override IEnumerable ListTableValuedFunctions(DiscoveredDatabase parent, IQuerySyntaxHelper querySyntaxHelper, - DbConnection connection, string database, DbTransaction transaction = null) => + DbConnection connection, string database, DbTransaction? transaction = null) => Enumerable.Empty(); public override DiscoveredStoredprocedure[] diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs index 53a24d6f..764982f1 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs @@ -88,13 +88,14 @@ public override string[] ListDatabases(DbConnection con) return [.. databases]; } - public override DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null) => new NpgsqlCommand(s, (NpgsqlConnection) con, (NpgsqlTransaction) transaction); + public override DbCommand GetCommand(string s, DbConnection con, DbTransaction? transaction = null) => new NpgsqlCommand(s, (NpgsqlConnection) + con, (NpgsqlTransaction?)transaction); - public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new NpgsqlDataAdapter((NpgsqlCommand) cmd); + public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new NpgsqlDataAdapter((NpgsqlCommand)cmd); public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) => new NpgsqlCommandBuilder(new NpgsqlDataAdapter((NpgsqlCommand) cmd)); - public override DbParameter GetParameter(string parameterName) => new NpgsqlParameter {ParameterName = parameterName}; + public override DbParameter GetParameter(string parameterName) => new NpgsqlParameter { ParameterName = parameterName }; public override DbConnection GetConnection(DbConnectionStringBuilder builder) => new NpgsqlConnection(builder.ConnectionString); diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs index b822bc86..610f524d 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs @@ -152,7 +152,7 @@ public override IEnumerable DiscoverTableValuedFunctionPara public override IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable, IManagedConnection connection, CultureInfo culture) => new PostgreSqlBulkCopy(discoveredTable, connection,culture); public override int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTable, DbCommand cmd, - IManagedTransaction transaction = null) + IManagedTransaction? transaction = null) { var autoIncrement = discoveredTable.DiscoverColumns(transaction).SingleOrDefault(static c => c.IsAutoIncrement); @@ -168,7 +168,7 @@ public override int ExecuteInsertReturningIdentity(DiscoveredTable discoveredTab } public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable table, DbConnection connection, - IManagedTransaction transaction = null) + IManagedTransaction? transaction = null) { const string sql = """ select c.constraint_name diff --git a/Tests/FAnsiTests/Aggregation/AggregationTests.cs b/Tests/FAnsiTests/Aggregation/AggregationTests.cs index 0be37af1..91eafd8b 100644 --- a/Tests/FAnsiTests/Aggregation/AggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/AggregationTests.cs @@ -81,7 +81,7 @@ private void SetupDatabaseTable(bool easy, string name) } } - protected static void AssertHasRow(DataTable dt, params object[] cells) + protected static void AssertHasRow(DataTable dt, params object?[] cells) { Assert.That(dt.Rows.Cast().Any(r => IsMatch(r, cells)),$"Did not find expected row:{string.Join("|", cells)}"); } @@ -92,9 +92,9 @@ protected static void AssertHasRow(DataTable dt, params object[] cells) /// /// /// - private static bool IsMatch(DataRow r, object[] cells) + private static bool IsMatch(DataRow r, object?[] cells) { - for(var i = 0 ; i diff --git a/Tests/FAnsiTests/DatabaseTests.cs b/Tests/FAnsiTests/DatabaseTests.cs index 4a636c14..c55ee824 100644 --- a/Tests/FAnsiTests/DatabaseTests.cs +++ b/Tests/FAnsiTests/DatabaseTests.cs @@ -135,24 +135,24 @@ protected void AssertCanCreateDatabases() Assert.Inconclusive("Test cannot run when AllowDatabaseCreation is false"); } - private static bool AreBasicallyEquals(object o, object o2, bool handleSlashRSlashN = true) + private static bool AreBasicallyEquals(object? o, object? o2, bool handleSlashRSlashN = true) { //if they are legit equals if (Equals(o, o2)) return true; //if they are null but basically the same - var oIsNull = o == null || o == DBNull.Value || o.ToString()?.Equals("0")==true; - var o2IsNull = o2 == null || o2 == DBNull.Value || o2.ToString()?.Equals("0")==true; + var oIsNull = o == null || o == DBNull.Value || o.ToString()?.Equals("0") == true; + var o2IsNull = o2 == null || o2 == DBNull.Value || o2.ToString()?.Equals("0") == true; if (oIsNull || o2IsNull) return oIsNull == o2IsNull; //they are not null so tostring them deals with int vs long etc that DbDataAdapters can be a bit flaky on if (handleSlashRSlashN) - return string.Equals(o.ToString()?.Replace("\r", "").Replace("\n", ""), o2.ToString()?.Replace("\r", "").Replace("\n", "")); + return string.Equals(o?.ToString()?.Replace("\r", "").Replace("\n", ""), o2?.ToString()?.Replace("\r", "").Replace("\n", "")); - return string.Equals(o.ToString(), o2.ToString()); + return string.Equals(o?.ToString(), o2?.ToString()); } protected static void AssertAreEqual(DataTable dt1, DataTable dt2) diff --git a/Tests/FAnsiTests/Equality/EqualityTests_ServerAndDatabase.cs b/Tests/FAnsiTests/Equality/EqualityTests_ServerAndDatabase.cs index e0abe6c8..1be2750b 100644 --- a/Tests/FAnsiTests/Equality/EqualityTests_ServerAndDatabase.cs +++ b/Tests/FAnsiTests/Equality/EqualityTests_ServerAndDatabase.cs @@ -14,7 +14,7 @@ public void SetUp() [TestCase("Server=fish fish fish", DatabaseType.MicrosoftSQLServer,"Server=fish fish fish", DatabaseType.MicrosoftSQLServer)] [TestCase(null, DatabaseType.MicrosoftSQLServer, null, DatabaseType.MicrosoftSQLServer)] [TestCase(null, DatabaseType.MicrosoftSQLServer, "", DatabaseType.MicrosoftSQLServer)] - public void EqualityTest_DiscoveredServer_AreEqual(string constr1, DatabaseType type1,string constr2, DatabaseType type2) + public void EqualityTest_DiscoveredServer_AreEqual(string? constr1, DatabaseType type1, string? constr2, DatabaseType type2) { var s1 = new DiscoveredServer(constr1, type1); var s2 = new DiscoveredServer(constr2, type2); @@ -38,13 +38,12 @@ public void EqualityTest_DiscoveredServer_AreEqual(string constr1, DatabaseType Assert.That(s2, Is.Not.EqualTo(s1)); Assert.That(s2.ExpectDatabase("MyDb"), Is.EqualTo(s1.ExpectDatabase("MyDb"))); Assert.That(s2.ExpectDatabase("MyDb").GetHashCode(), Is.EqualTo(s1.ExpectDatabase("MyDb").GetHashCode())); - } [TestCase("Server=fish fish fish", DatabaseType.MicrosoftSQLServer, "Server=fish fish fish;Integrated Security=true", DatabaseType.MicrosoftSQLServer)] [TestCase("Server=fish fish fish", DatabaseType.MicrosoftSQLServer, "Server=fish fish fish", DatabaseType.MySql)] [TestCase(null, DatabaseType.MicrosoftSQLServer, "", DatabaseType.MySql)] - public void EqualityTest_DiscoveredServer_AreNotEqual(string constr1, DatabaseType type1, string constr2, DatabaseType type2) + public void EqualityTest_DiscoveredServer_AreNotEqual(string? constr1, DatabaseType type1, string constr2, DatabaseType type2) { var s1 = new DiscoveredServer(constr1, type1); var s2 = new DiscoveredServer(constr2, type2); diff --git a/Tests/FAnsiTests/Equality/EqualityTests_TableAndColumn.cs b/Tests/FAnsiTests/Equality/EqualityTests_TableAndColumn.cs index 0c6659b3..d96a628e 100644 --- a/Tests/FAnsiTests/Equality/EqualityTests_TableAndColumn.cs +++ b/Tests/FAnsiTests/Equality/EqualityTests_TableAndColumn.cs @@ -17,7 +17,7 @@ public void SetUp() [TestCase("MyTable", null, "MyTable", "dBo")] [TestCase("MyTable", null, "MyTable", "")] [TestCase("MyTable", "", "MyTable", "dbo")] - public void EqualityTest_DiscoveredTable_AreEqual(string table1, string schema1, string table2, string schema2) + public void EqualityTest_DiscoveredTable_AreEqual(string table1, string? schema1, string table2, string? schema2) { var s = new DiscoveredServer("Server=fish", DatabaseType.MicrosoftSQLServer); @@ -42,7 +42,7 @@ public void EqualityTest_DiscoveredTable_AreEqual(string table1, string schema1, [TestCase(DatabaseType.MicrosoftSQLServer, "Server=fish", "MyDb", "MyTable", null, DatabaseType.MicrosoftSQLServer, "Server=fish", "MyDb2", "MyTable", null)] [TestCase(DatabaseType.MicrosoftSQLServer, "Server=fish", "MyDb", "MyTable", null, DatabaseType.MicrosoftSQLServer, "Server=fish2", "MyDb", "MyTable", null)] [TestCase(DatabaseType.MicrosoftSQLServer, "Server=fish", "MyDb", "MyTable", null, DatabaseType.MySql, "Server=fish", "MyDb", "MyTable", null)] - public void EqualityTest_DiscoveredTable_AreNotEqual(DatabaseType type1, string constr1, string dbname1, string tablename1, string schema1, DatabaseType type2, string constr2, string dbname2, string tablename2, string schema2) + public void EqualityTest_DiscoveredTable_AreNotEqual(DatabaseType type1, string constr1, string dbname1, string tablename1, string? schema1, DatabaseType type2, string constr2, string dbname2, string tablename2, string? schema2) { var s1 = new DiscoveredServer(constr1, type1); var s2 = new DiscoveredServer(constr2, type2); diff --git a/Tests/FAnsiTests/PackageListIsCorrectTests.cs b/Tests/FAnsiTests/PackageListIsCorrectTests.cs index cd89bdee..8260f1d6 100644 --- a/Tests/FAnsiTests/PackageListIsCorrectTests.cs +++ b/Tests/FAnsiTests/PackageListIsCorrectTests.cs @@ -29,7 +29,7 @@ public sealed partial class PackageListIsCorrectTests /// /// [TestCase] - public void TestPackagesDocumentCorrect(string rootPath=null) + public void TestPackagesDocumentCorrect(string? rootPath=null) { var root= FindRoot(rootPath); var undocumented = new StringBuilder(); @@ -72,7 +72,7 @@ public void TestPackagesDocumentCorrect(string rootPath=null) /// /// /// - private static DirectoryInfo FindRoot(string path = null) + private static DirectoryInfo FindRoot(string? path = null) { if (path != null) { diff --git a/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs b/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs index 253d90e1..59374a9d 100644 --- a/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs +++ b/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs @@ -140,9 +140,10 @@ public void SyntaxHelperTest_GetRuntimeName_Oracle() [TestCase("count(*) as Frank32","count(*)","Frank32")] [TestCase("CAST([dave] as int) as [number]","CAST([dave] as int)","number")] [TestCase("CAST([dave] as int)","CAST([dave] as int)",null)] - public void SyntaxHelperTest_SplitLineIntoSelectSQLAndAlias(string line, string expectedSelectSql, string expectedAlias) + public void SyntaxHelperTest_SplitLineIntoSelectSQLAndAlias(string line, string expectedSelectSql, string? expectedAlias) { - foreach (var syntaxHelper in new []{DatabaseType.Oracle,DatabaseType.MySql,DatabaseType.MicrosoftSQLServer}.Select(t => ImplementationManager.GetImplementation(t).GetQuerySyntaxHelper())) + foreach (var syntaxHelper in new[] { DatabaseType.Oracle, DatabaseType.MySql, DatabaseType.MicrosoftSQLServer } + .Select(static t => ImplementationManager.GetImplementation(t).GetQuerySyntaxHelper())) Assert.Multiple(() => { Assert.That(syntaxHelper.SplitLineIntoSelectSQLAndAlias(line, out var selectSQL, out var alias), Is.EqualTo(expectedAlias != null)); @@ -176,14 +177,14 @@ public void Test_NameValidation(DatabaseType dbType) { var syntaxHelper = ImplementationManager.GetImplementation(dbType).GetQuerySyntaxHelper(); - Assert.Throws(()=>syntaxHelper.ValidateDatabaseName(null)); - Assert.Throws(()=>syntaxHelper.ValidateDatabaseName(" ")); - Assert.Throws(()=>syntaxHelper.ValidateDatabaseName("db.table")); - Assert.Throws(()=>syntaxHelper.ValidateDatabaseName("db(lol)")); - Assert.Throws(()=>syntaxHelper.ValidateDatabaseName(new string('A', syntaxHelper.MaximumDatabaseLength+1))); + Assert.Throws(() => syntaxHelper.ValidateDatabaseName(null)); + Assert.Throws(() => syntaxHelper.ValidateDatabaseName(" ")); + Assert.Throws(() => syntaxHelper.ValidateDatabaseName("db.table")); + Assert.Throws(() => syntaxHelper.ValidateDatabaseName("db(lol)")); + Assert.Throws(() => syntaxHelper.ValidateDatabaseName(new string('A', syntaxHelper.MaximumDatabaseLength+1))); - Assert.DoesNotThrow(()=>syntaxHelper.ValidateDatabaseName("A")); - Assert.DoesNotThrow(()=>syntaxHelper.ValidateDatabaseName(new string('A', syntaxHelper.MaximumDatabaseLength))); + Assert.DoesNotThrow(() =>syntaxHelper.ValidateDatabaseName("A")); + Assert.DoesNotThrow(() =>syntaxHelper.ValidateDatabaseName(new string('A', syntaxHelper.MaximumDatabaseLength))); } [Test] diff --git a/Tests/FAnsiTests/Server/ServerTests.cs b/Tests/FAnsiTests/Server/ServerTests.cs index 659daec7..e2f29e82 100644 --- a/Tests/FAnsiTests/Server/ServerTests.cs +++ b/Tests/FAnsiTests/Server/ServerTests.cs @@ -21,7 +21,9 @@ public void Server_Exists(DatabaseType type) public void Server_Constructors(DatabaseType dbType) { var helper = ImplementationManager.GetImplementation(dbType).GetServerHelper(); - var server = new DiscoveredServer(helper.GetConnectionStringBuilder("localhost", null,"franko","wacky").ConnectionString,dbType); + var server = + new DiscoveredServer( + helper.GetConnectionStringBuilder("localhost", null, "franko", "wacky").ConnectionString, dbType); Assert.That(server.Name, Is.EqualTo("localhost")); } diff --git a/Tests/FAnsiTests/Table/BulkInsertTest.cs b/Tests/FAnsiTests/Table/BulkInsertTest.cs index c990b20d..8c0e2344 100644 --- a/Tests/FAnsiTests/Table/BulkInsertTest.cs +++ b/Tests/FAnsiTests/Table/BulkInsertTest.cs @@ -842,23 +842,22 @@ public void TestBulkInsert_BadDecimalFormat_DecimalError(DatabaseType type) using var bulk = tbl.BeginBulkInsert(); bulk.Timeout = 30; - Exception ex = null; + Exception? ex = null; try { bulk.Upload(dt); } - catch(Exception e) + catch (Exception e) { ex = e; } - Assert.That(ex, Is.Not.Null, "Expected upload to fail because value on row 2 is bad"); - Assert.Multiple(() => { - Assert.That(ex.Message, Is.EqualTo("Failed to parse value '.' in column 'score'")); - Assert.That(ex.InnerException, Is.Not.Null, "Expected parse error to be an inner exception"); + Assert.That(ex, Is.Not.Null, "Expected upload to fail because value on row 2 is bad"); + Assert.That(ex?.Message, Is.EqualTo("Failed to parse value '.' in column 'score'")); + Assert.That(ex?.InnerException, Is.Not.Null, "Expected parse error to be an inner exception"); + Assert.That(ex?.InnerException?.Message, Does.Contain("Could not parse string value '.' with Decider Type:DecimalTypeDecider")); }); - Assert.That(ex.InnerException?.Message, Does.Contain("Could not parse string value '.' with Decider Type:DecimalTypeDecider")); } } \ No newline at end of file diff --git a/Tests/FAnsiTests/Table/CreateTableTests.cs b/Tests/FAnsiTests/Table/CreateTableTests.cs index 8a058fad..3c9679af 100644 --- a/Tests/FAnsiTests/Table/CreateTableTests.cs +++ b/Tests/FAnsiTests/Table/CreateTableTests.cs @@ -567,7 +567,7 @@ public void CreateTable_GuessSettings_InArgs_TF(DatabaseType dbType, bool treatA dt.Rows.Add("T"); dt.Rows.Add("F"); - var args = new CreateTableArgs(db,"Hb",null,dt,false); + var args = new CreateTableArgs(db, "Hb", null, dt, false); Assert.Multiple(() => { Assert.That(GuessSettingsFactory.Defaults.CharCanBeBoolean, Is.EqualTo(args.GuessSettings.CharCanBeBoolean), "Default should match the static default"); diff --git a/Tests/FAnsiTests/Table/DataTypeAdjusterTests.cs b/Tests/FAnsiTests/Table/DataTypeAdjusterTests.cs index 821e3717..6db09deb 100644 --- a/Tests/FAnsiTests/Table/DataTypeAdjusterTests.cs +++ b/Tests/FAnsiTests/Table/DataTypeAdjusterTests.cs @@ -25,7 +25,9 @@ internal sealed class DataTypeAdjusterTestsPadder : IDatabaseColumnRequestAdjust { public void AdjustColumns(List columns) { - columns[0].TypeRequested.Width = 12; +#pragma warning disable CS8602 // Dereference of a possibly null reference - spurious + if (columns[0].TypeRequested is not null) columns[0].TypeRequested.Width = 12; +#pragma warning restore CS8602 // Dereference of a possibly null reference. } } } \ No newline at end of file From faa00073d647acff32602fde3e6a579eea074643 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 1 Feb 2024 17:05:41 -0600 Subject: [PATCH 6/7] Nullity fixups, bump TypeGuesser --- FAnsiSql/Discovery/DiscoveredColumn.cs | 4 ++-- FAnsiSql/Discovery/DiscoveredDatabase.cs | 8 +++---- .../Discovery/DiscoveredDatabaseHelper.cs | 3 ++- FAnsiSql/Discovery/DiscoveredServer.cs | 4 ++-- FAnsiSql/Discovery/DiscoveredServerHelper.cs | 21 ++++++++++--------- FAnsiSql/Discovery/DiscoveredTable.cs | 12 +++++------ FAnsiSql/Discovery/DiscoveredTableHelper.cs | 2 +- .../Discovery/IDiscoveredDatabaseHelper.cs | 2 +- FAnsiSql/Discovery/IDiscoveredServerHelper.cs | 10 ++++----- .../ISupplementalColumnInformation.cs | 2 +- .../AggregateCustomLineCollection.cs | 10 ++++----- .../QuerySyntax/IQuerySyntaxHelper.cs | 17 ++++++++------- .../QuerySyntax/QuerySyntaxHelperFactory.cs | 2 +- FAnsiSql/Discovery/QuerySyntaxHelper.cs | 17 ++++++++------- .../TableCreation/CreateTableArgs.cs | 4 ++-- .../TypeTranslation/ITypeTranslater.cs | 4 ++-- .../TypeTranslation/TypeTranslater.cs | 4 ++-- FAnsiSql/FAnsi.csproj | 6 +----- .../MicrosoftQuerySyntaxHelper.cs | 6 +++--- .../MicrosoftSQLDatabaseHelper.cs | 14 ++++++------- .../MicrosoftSQL/MicrosoftSQLTableHelper.cs | 7 +++---- .../Implementations/MySql/MySqlBulkCopy.cs | 3 +-- .../Implementations/MySql/MySqlTableHelper.cs | 2 -- .../Implementations/Oracle/OracleBulkCopy.cs | 2 +- .../Oracle/OracleTableHelper.cs | 6 +++--- .../PostgreSql/PostgreSqlServerHelper.cs | 6 +++--- .../PostgreSql/PostgreSqlTableHelper.cs | 7 +++---- FAnsiSql/Naming/IHasRuntimeName.cs | 2 +- Tests/FAnsiTests/FAnsiTests.csproj | 2 +- Tests/FAnsiTests/Table/CreateTableTests.cs | 1 - 30 files changed, 92 insertions(+), 98 deletions(-) diff --git a/FAnsiSql/Discovery/DiscoveredColumn.cs b/FAnsiSql/Discovery/DiscoveredColumn.cs index e75fb686..7b4f8af7 100644 --- a/FAnsiSql/Discovery/DiscoveredColumn.cs +++ b/FAnsiSql/Discovery/DiscoveredColumn.cs @@ -45,7 +45,7 @@ public sealed class DiscoveredColumn(DiscoveredTable table, string name, bool al /// /// The DBMS proprietary column specific collation e.g. "Latin1_General_CS_AS_KS_WS" /// - public string Collation { get; set; } + public string? Collation { get; set; } /// /// The data type of the column found (includes String Length and Scale/Precision). @@ -64,7 +64,7 @@ public sealed class DiscoveredColumn(DiscoveredTable table, string name, bool al /// The unqualified name of the column e.g. "MyCol" /// /// - public string GetRuntimeName() => _querySyntaxHelper.GetRuntimeName(_name); + public string? GetRuntimeName() => _querySyntaxHelper.GetRuntimeName(_name); /// /// The fully qualified name of the column e.g. [MyDb].dbo.[MyTable].[MyCol] or `MyDb`.`MyCol` diff --git a/FAnsiSql/Discovery/DiscoveredDatabase.cs b/FAnsiSql/Discovery/DiscoveredDatabase.cs index 2b24ed27..eb0601f5 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabase.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabase.cs @@ -78,13 +78,13 @@ public IEnumerable DiscoverTableValuedFunctions(I /// Returns the name of the database without any qualifiers /// /// - public string GetRuntimeName() => _querySyntaxHelper.GetRuntimeName(_database); + public string? GetRuntimeName() => _querySyntaxHelper.GetRuntimeName(_database); /// /// Returns the wrapped e.g. "[MyDatabase]" name of the database including escaping e.g. if you wanted to name a database "][nquisitor" (which would return "[]][nquisitor]"). /// /// - public string GetWrappedName() => _querySyntaxHelper.EnsureWrapped(GetRuntimeName()); + public string? GetWrappedName() => _querySyntaxHelper.EnsureWrapped(GetRuntimeName()); /// /// Creates an expectation (See ) that there is a table with the given name in the database. @@ -127,7 +127,7 @@ public DiscoveredTable ExpectTable(string tableName, string? schema = null, Tabl /// public bool Exists(IManagedTransaction? transaction = null) { - return Server.DiscoverDatabases().Any(db => db.GetRuntimeName().Equals(GetRuntimeName(),StringComparison.InvariantCultureIgnoreCase)); + return Server.DiscoverDatabases().Any(db => db.GetRuntimeName()?.Equals(GetRuntimeName(), StringComparison.InvariantCultureIgnoreCase) == true); } /// @@ -266,7 +266,7 @@ public void CreateSchema(string name) /// NOTE: you must know how to map this data path to a shared path you can access! /// /// Local drive data path where the files are stored - public DirectoryInfo Detach() => Helper.Detach(this); + public DirectoryInfo? Detach() => Helper.Detach(this); /// /// Creates a local (to the DBMS server) backup of the database. Implementations may vary but should be the simplest database type diff --git a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs index 04b44209..143b9f9c 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs @@ -243,12 +243,13 @@ public virtual string GetForeignKeyConstraintSql(string foreignTable, IQuerySynt REFERENCES {primaryKeyTable.GetFullyQualifiedName()}({string.Join(",", foreignKeyPairs.Values.Select(v => syntaxHelper.EnsureWrapped(v.GetRuntimeName())))}) {(cascadeDelete ? " on delete cascade" : "")} """; } + public string GetForeignKeyConstraintNameFor(DiscoveredTable foreignTable, DiscoveredTable primaryTable) => GetForeignKeyConstraintNameFor(foreignTable.GetRuntimeName(), primaryTable.GetRuntimeName()); private static string GetForeignKeyConstraintNameFor(string foreignTable, string primaryTable) => MakeSensibleConstraintName("FK_", $"{foreignTable}_{primaryTable}"); - public abstract DirectoryInfo Detach(DiscoveredDatabase database); + public abstract DirectoryInfo? Detach(DiscoveredDatabase database); public abstract void CreateBackup(DiscoveredDatabase discoveredDatabase, string backupName); diff --git a/FAnsiSql/Discovery/DiscoveredServer.cs b/FAnsiSql/Discovery/DiscoveredServer.cs index b111d554..3f4d37f8 100644 --- a/FAnsiSql/Discovery/DiscoveredServer.cs +++ b/FAnsiSql/Discovery/DiscoveredServer.cs @@ -43,12 +43,12 @@ public sealed class DiscoveredServer : IMightNotExist /// /// Returns the username portion of if specified /// - public string ExplicitUsernameIfAny => Helper.GetExplicitUsernameIfAny(Builder); + public string? ExplicitUsernameIfAny => Helper.GetExplicitUsernameIfAny(Builder); /// /// Returns the password portion of if specified /// - public string ExplicitPasswordIfAny => Helper.GetExplicitPasswordIfAny(Builder); + public string? ExplicitPasswordIfAny => Helper.GetExplicitPasswordIfAny(Builder); /// /// Creates a new server pointed at the server. diff --git a/FAnsiSql/Discovery/DiscoveredServerHelper.cs b/FAnsiSql/Discovery/DiscoveredServerHelper.cs index 7861c121..00960bd0 100644 --- a/FAnsiSql/Discovery/DiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredServerHelper.cs @@ -83,10 +83,10 @@ protected virtual void EnforceKeywords(DbConnectionStringBuilder builder) protected abstract string DatabaseKeyName { get; } protected virtual string ConnectionTimeoutKeyName => "ConnectionTimeout"; - public string GetServerName(DbConnectionStringBuilder builder) + public string? GetServerName(DbConnectionStringBuilder builder) { - var s = (string) builder[ServerKeyName]; - return string.IsNullOrWhiteSpace(s)?null:s; + var s = (string)builder[ServerKeyName]; + return string.IsNullOrWhiteSpace(s) ? null : s; } public DbConnectionStringBuilder ChangeServer(DbConnectionStringBuilder builder, string newServer) @@ -159,11 +159,12 @@ public bool RespondsWithinTime(DbConnectionStringBuilder builder, int timeoutInS return false; } } - public abstract string GetExplicitUsernameIfAny(DbConnectionStringBuilder builder); - public abstract string GetExplicitPasswordIfAny(DbConnectionStringBuilder builder); - public abstract Version GetVersion(DiscoveredServer server); - private readonly Regex rVagueVersion = rVagueVersionRe(); + public abstract string? GetExplicitUsernameIfAny(DbConnectionStringBuilder builder); + public abstract string? GetExplicitPasswordIfAny(DbConnectionStringBuilder builder); + public abstract Version? GetVersion(DiscoveredServer server); + + private static readonly Regex _rVagueVersion = RVagueVersionRe(); /// /// Number of seconds to allow to run for before timing out. @@ -178,17 +179,17 @@ public bool RespondsWithinTime(DbConnectionStringBuilder builder, int timeoutInS /// /// /// - protected Version CreateVersionFromString(string versionString) + protected static Version? CreateVersionFromString(string versionString) { if (Version.TryParse(versionString, out var result)) return result; - var m = rVagueVersion.Match(versionString); + var m = _rVagueVersion.Match(versionString); return m.Success ? Version.Parse(m.Value) : //whatever the string was it didn't even remotely resemble a Version null; } [GeneratedRegex(@"\d+\.\d+(\.\d+)?(\.\d+)?", RegexOptions.Compiled | RegexOptions.CultureInvariant)] - private static partial Regex rVagueVersionRe(); + private static partial Regex RVagueVersionRe(); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/DiscoveredTable.cs b/FAnsiSql/Discovery/DiscoveredTable.cs index 493f0ef9..d1e1e8e0 100644 --- a/FAnsiSql/Discovery/DiscoveredTable.cs +++ b/FAnsiSql/Discovery/DiscoveredTable.cs @@ -41,7 +41,7 @@ public class DiscoveredTable : IHasFullyQualifiedNameToo, IMightNotExist, IHasQu /// /// Null if not supported by the DBMS (e.g. MySql) /// - public readonly string Schema; + public readonly string? Schema; /// /// Whether the table referenced is a normal table, view or table valued function (see derived class ) @@ -88,7 +88,7 @@ public virtual bool Exists(IManagedTransaction? transaction = null) /// Returns the unqualified name of the table e.g. "MyTable" /// /// - public virtual string GetRuntimeName() => QuerySyntaxHelper.GetRuntimeName(TableName); + public virtual string? GetRuntimeName() => QuerySyntaxHelper.GetRuntimeName(TableName); /// /// Returns the fully qualified (including schema if appropriate) name of the table e.g. [MyDb].dbo.[MyTable] or `MyDb`.`MyTable` @@ -100,7 +100,7 @@ public virtual bool Exists(IManagedTransaction? transaction = null) /// Returns the wrapped e.g. "[MyTbl]" name of the table including escaping e.g. if you wanted to name a table "][nquisitor" (which would return "[]][nquisitor]"). Use to return the full name including table/database/schema. /// /// - public string GetWrappedName() => QuerySyntaxHelper.EnsureWrapped(GetRuntimeName()); + public string? GetWrappedName() => QuerySyntaxHelper.EnsureWrapped(GetRuntimeName()); /// /// Connects to the server and returns a list of columns found in the table as . @@ -394,12 +394,12 @@ public void CreatePrimaryKey(DatabaseOperationArgs args, params DiscoveredColumn /// /// /// - public int Insert(Dictionary toInsert, CultureInfo? culture, IManagedTransaction? transaction=null) + public int Insert(Dictionary toInsert, CultureInfo? culture, IManagedTransaction? transaction = null) { var syntaxHelper = GetQuerySyntaxHelper(); var server = Database.Server; - var _parameterNames = syntaxHelper.GetParameterNamesFor(toInsert.Keys.ToArray(), static c=>c.GetRuntimeName()); + var _parameterNames = syntaxHelper.GetParameterNamesFor(toInsert.Keys.ToArray(), static c => c.GetRuntimeName()); using var connection = Database.Server.GetManagedConnection(transaction); var sql = @@ -481,7 +481,7 @@ public bool Equals(DiscoveredTable? other) && Equals(Database, other.Database) && TableType == other.TableType; } - private string GetSchemaWithDefaultForNull() => + private string? GetSchemaWithDefaultForNull() => //for "dbo, "" and null are all considered the same string.IsNullOrWhiteSpace(Schema) ? GetQuerySyntaxHelper().GetDefaultSchemaIfAny() : Schema; diff --git a/FAnsiSql/Discovery/DiscoveredTableHelper.cs b/FAnsiSql/Discovery/DiscoveredTableHelper.cs index cfe65ffa..14ce4aeb 100644 --- a/FAnsiSql/Discovery/DiscoveredTableHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredTableHelper.cs @@ -277,7 +277,7 @@ public virtual bool RequiresLength(string columnType) => _ => false }; - public bool HasPrecisionAndScale(string columnType) => + public static bool HasPrecisionAndScale(string columnType) => columnType.ToLowerInvariant() switch { "decimal" => true, diff --git a/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs b/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs index 8e408e3a..c22f9b37 100644 --- a/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs @@ -46,7 +46,7 @@ string GetCreateTableSql(DiscoveredDatabase database, string tableName, Database string GetForeignKeyConstraintSql(string foreignTable, IQuerySyntaxHelper syntaxHelper, Dictionary foreignKeyPairs, bool cascadeDelete, string? constraintName = null); - DirectoryInfo Detach(DiscoveredDatabase database); + DirectoryInfo? Detach(DiscoveredDatabase database); void CreateBackup(DiscoveredDatabase discoveredDatabase, string backupName); /// diff --git a/FAnsiSql/Discovery/IDiscoveredServerHelper.cs b/FAnsiSql/Discovery/IDiscoveredServerHelper.cs index d2f81ce4..c41f9c58 100644 --- a/FAnsiSql/Discovery/IDiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredServerHelper.cs @@ -21,7 +21,7 @@ public interface IDiscoveredServerHelper DbParameter GetParameter(string parameterName); DbConnection GetConnection(DbConnectionStringBuilder builder); - DbConnectionStringBuilder GetConnectionStringBuilder(string connectionString); + DbConnectionStringBuilder GetConnectionStringBuilder(string? connectionString); /// /// Returns a new connection string builder with the supplied parameters. Note that if a concept is not supported in the @@ -35,7 +35,7 @@ public interface IDiscoveredServerHelper /// DbConnectionStringBuilder GetConnectionStringBuilder(string server, string? database, string username, string password); - string GetServerName(DbConnectionStringBuilder builder); + string? GetServerName(DbConnectionStringBuilder builder); DbConnectionStringBuilder ChangeServer(DbConnectionStringBuilder builder, string newServer); string GetCurrentDatabase(DbConnectionStringBuilder builder); @@ -56,7 +56,7 @@ public interface IDiscoveredServerHelper Dictionary DescribeServer(DbConnectionStringBuilder builder); bool RespondsWithinTime(DbConnectionStringBuilder builder, int timeoutInSeconds, out Exception? exception); - string GetExplicitUsernameIfAny(DbConnectionStringBuilder builder); - string GetExplicitPasswordIfAny(DbConnectionStringBuilder builder); - Version GetVersion(DiscoveredServer server); + string? GetExplicitUsernameIfAny(DbConnectionStringBuilder builder); + string? GetExplicitPasswordIfAny(DbConnectionStringBuilder builder); + Version? GetVersion(DiscoveredServer server); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/ISupplementalColumnInformation.cs b/FAnsiSql/Discovery/ISupplementalColumnInformation.cs index 99ad179a..47bca0b2 100644 --- a/FAnsiSql/Discovery/ISupplementalColumnInformation.cs +++ b/FAnsiSql/Discovery/ISupplementalColumnInformation.cs @@ -19,5 +19,5 @@ public interface ISupplementalColumnInformation /// /// Records the collation of the column in the underlying database table this record points at if explicitly declared by dbms (only applicable for char datatypes) /// - string Collation { get; set; } + string? Collation { get; set; } } \ No newline at end of file diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs index 620af7cb..73d13341 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs @@ -35,30 +35,30 @@ private void Validate() /// /// The single aggregate function line e.g. "count(distinct chi) as Fish," /// - public CustomLine CountSelect => Lines.SingleOrDefault(static l => l.Role == CustomLineRole.CountFunction && l.LocationToInsert == QueryComponent.QueryTimeColumn); + public CustomLine? CountSelect => Lines.SingleOrDefault(static l => l.Role == CustomLineRole.CountFunction && l.LocationToInsert == QueryComponent.QueryTimeColumn); /// /// The (optional) single line of SELECT SQL which is the Axis join column e.g. "[MyDb]..[mytbl].[AdmissionDate] as Admt," /// - public CustomLine AxisSelect => Lines.SingleOrDefault(static l => l.Role == CustomLineRole.Axis && l.LocationToInsert == QueryComponent.QueryTimeColumn); + public CustomLine? AxisSelect => Lines.SingleOrDefault(static l => l.Role == CustomLineRole.Axis && l.LocationToInsert == QueryComponent.QueryTimeColumn); /// /// The (optional) single line of GROUP BY SQL which matches exactly the SQL of /// - public CustomLine AxisGroupBy => Lines.SingleOrDefault(static l => l.LocationToInsert == QueryComponent.GroupBy && l.Role == CustomLineRole.Axis); + public CustomLine? AxisGroupBy => Lines.SingleOrDefault(static l => l.LocationToInsert == QueryComponent.GroupBy && l.Role == CustomLineRole.Axis); /// /// The (optional) single line of SELECT SQL which is the dynamic pivot column e.g. "[MyDb]..[mytbl].[Healthboard] as hb," /// - public CustomLine PivotSelect => Lines.SingleOrDefault(static l => l.Role == CustomLineRole.Pivot && l.LocationToInsert == QueryComponent.QueryTimeColumn); + public CustomLine? PivotSelect => Lines.SingleOrDefault(static l => l.Role == CustomLineRole.Pivot && l.LocationToInsert == QueryComponent.QueryTimeColumn); /// /// The (optional) single line of ORDER BY SQL which restricts which records are returned when doing a dynamic pivot e.g. only dynamic pivot on the /// top 5 drugs ordered by SUM of prescriptions /// - public CustomLine TopXOrderBy => Lines.SingleOrDefault(static l => l.LocationToInsert == QueryComponent.OrderBy && l.Role == CustomLineRole.TopX); + public CustomLine? TopXOrderBy => Lines.SingleOrDefault(static l => l.LocationToInsert == QueryComponent.OrderBy && l.Role == CustomLineRole.TopX); /// /// Returns all concatenated SQL for all between the inclusive boundaries from/to diff --git a/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs index 1cc82767..8330447d 100644 --- a/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data.Common; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using FAnsi.Discovery.QuerySyntax.Aggregation; using FAnsi.Discovery.QuerySyntax.Update; @@ -31,7 +32,7 @@ public interface IQuerySyntaxHelper /// /// Function to convert the to a string e.g. c.ColumnName if DataColumn /// - Dictionary GetParameterNamesFor(T[] columns, Func toStringFunc) where T : notnull; + Dictionary GetParameterNamesFor(T[] columns, Func toStringFunc) where T : notnull; IAggregateHelper AggregateHelper { get; } IUpdateHelper UpdateHelper { get; set; } @@ -58,7 +59,7 @@ public interface IQuerySyntaxHelper char ParameterSymbol { get; } - string GetRuntimeName(string s); + string? GetRuntimeName(string? s); bool TryGetRuntimeName(string s, out string? name); @@ -79,8 +80,8 @@ public interface IQuerySyntaxHelper /// string? EnsureWrapped(string? databaseOrTableName); - string EnsureFullyQualified(string databaseName, string? schemaName, string tableName); - string EnsureFullyQualified(string databaseName, string? schemaName, string tableName, string columnName, bool isTableValuedFunction = false); + string EnsureFullyQualified(string? databaseName, string? schemaName, string tableName); + string EnsureFullyQualified(string? databaseName, string? schemaName, string tableName, string columnName, bool isTableValuedFunction = false); /// /// Returns the given escaped e.g. doubling up single quotes. Does not add any wrapping. @@ -194,17 +195,17 @@ public interface IQuerySyntaxHelper /// /// Returns false if the supplied name is invalid (because it is too long or contains unsupported characters) /// - bool IsValidDatabaseName(string databaseName, out string? reason); + bool IsValidDatabaseName(string databaseName, [NotNullWhen(false)] out string? reason); /// /// Returns false if the supplied name is invalid (because it is too long or contains unsupported characters) /// - bool IsValidTableName(string tableName, out string reason); + bool IsValidTableName(string tableName, [NotNullWhen(false)] out string reason); /// /// Returns false if the supplied name is invalid (because it is too long or contains unsupported characters) /// - bool IsValidColumnName(string columnName, out string reason); + bool IsValidColumnName(string columnName, [NotNullWhen(false)] out string? reason); /// @@ -212,7 +213,7 @@ public interface IQuerySyntaxHelper /// If schemas are not supported (e.g. MySql) then null is returned /// /// - string GetDefaultSchemaIfAny(); + string? GetDefaultSchemaIfAny(); } public enum MandatoryScalarFunctions diff --git a/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs b/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs index fde4e7ce..c6ead0a6 100644 --- a/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs +++ b/FAnsiSql/Discovery/QuerySyntax/QuerySyntaxHelperFactory.cs @@ -5,7 +5,7 @@ namespace FAnsi.Discovery.QuerySyntax; /// /// Translates a DatabaseType into the correct IQuerySyntaxHelper. /// -public sealed class QuerySyntaxHelperFactory +public static class QuerySyntaxHelperFactory { public static IQuerySyntaxHelper Create(DatabaseType type) => ImplementationManager.GetImplementation(type).GetQuerySyntaxHelper(); } \ No newline at end of file diff --git a/FAnsiSql/Discovery/QuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntaxHelper.cs index 223fbf21..db831129 100644 --- a/FAnsiSql/Discovery/QuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntaxHelper.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Text; @@ -70,7 +71,7 @@ public abstract partial class QuerySyntaxHelper( /// " AS " qualifier is used explicitly. The capture groups of this Regex must match /// /// - protected Regex GetAliasRegex() => + private Regex GetAliasRegex() => //whitespace followed by as and more whitespace //Then any word (optionally bounded by a table name qualifier) //alias is a word @@ -111,7 +112,7 @@ public static string GetParameterNameFromDeclarationSQL(string parameterSQL) public bool IsValidParameterName(string parameterSQL) => ParameterNamesRegex.IsMatch(parameterSQL); - public virtual string GetRuntimeName(string s) + public virtual string? GetRuntimeName(string? s) { if (string.IsNullOrWhiteSpace(s)) return s; @@ -291,13 +292,13 @@ public static string MakeHeaderNameSensible(string header) return adjustedHeader; } - public string GetSensibleEntityNameFromString(string potentiallyDodgyName) + public string GetSensibleEntityNameFromString(string? potentiallyDodgyName) { potentiallyDodgyName = GetRuntimeName(potentiallyDodgyName); //replace anything that isn't a digit, letter or underscore with underscores var r = NotAlphaNumRe(); - var adjustedHeader = r.Replace(potentiallyDodgyName, "_"); + var adjustedHeader = r.Replace(potentiallyDodgyName ?? string.Empty, "_"); //if it starts with a digit (illegal) put an underscore before it if (StartsDigitsRe().IsMatch(adjustedHeader)) @@ -384,25 +385,25 @@ public void ValidateColumnName(string columnName) throw new RuntimeNameException(reason); } - public bool IsValidDatabaseName(string? databaseName, out string? reason) + public bool IsValidDatabaseName(string? databaseName, [NotNullWhen(false)] out string? reason) { reason = ValidateName(databaseName, "Database", MaximumDatabaseLength); return string.IsNullOrWhiteSpace(reason); } - public bool IsValidTableName(string tableName,out string reason) + public bool IsValidTableName(string tableName, [NotNullWhen(false)] out string? reason) { reason = ValidateName(tableName, "Table", MaximumTableLength); return string.IsNullOrWhiteSpace(reason); } - public bool IsValidColumnName(string columnName,out string reason) + public bool IsValidColumnName(string columnName, [NotNullWhen(false)] out string? reason) { reason = ValidateName(columnName, "Column", MaximumColumnLength); return string.IsNullOrWhiteSpace(reason); } - public virtual string GetDefaultSchemaIfAny() => null; + public virtual string? GetDefaultSchemaIfAny() => null; /// /// returns null if the name is valid. Otherwise a string describing why it is invalid. diff --git a/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs b/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs index 05aebc7e..b9fd2f2e 100644 --- a/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs +++ b/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs @@ -33,12 +33,12 @@ public sealed class CreateTableArgs(DiscoveredDatabase database, string tableNam /// Optional - Columns are normally created based on supplied DataTable data rows. If this is set then the Type specified here will /// be used instead. /// - public DatabaseColumnRequest[] ExplicitColumnDefinitions { get; set; } + public DatabaseColumnRequest[]? ExplicitColumnDefinitions { get; set; } /// /// Set this to make last minute changes to column datatypes before table creation /// - public IDatabaseColumnRequestAdjuster Adjuster { get; set; } + public IDatabaseColumnRequestAdjuster? Adjuster { get; set; } /// /// Link between columns that you want to create in your table and existing columns () that diff --git a/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs b/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs index 941c3d99..34094e71 100644 --- a/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs +++ b/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs @@ -52,7 +52,7 @@ public interface ITypeTranslater [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] - Type TryGetCSharpTypeForSQLDBType(string sqlType); + Type? TryGetCSharpTypeForSQLDBType(string sqlType); /// /// Returns true if the string could be reconciled into a known C# Type. Do not use this @@ -70,7 +70,7 @@ public interface ITypeTranslater Guesser GetGuesserFor(DiscoveredColumn discoveredColumn); int GetLengthIfString(string sqlType); - DecimalSize GetDigitsBeforeAndAfterDecimalPointIfDecimal(string sqlType); + DecimalSize? GetDigitsBeforeAndAfterDecimalPointIfDecimal(string sqlType); /// /// Translates the given sqlType which must be an SQL string compatible with this TypeTranslater e.g. varchar(10) into the destination ITypeTranslater diff --git a/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs b/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs index 2f5fe7b8..78bdbd84 100644 --- a/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs +++ b/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs @@ -163,7 +163,7 @@ public Type GetCSharpTypeForSQLDBType(string sqlType) => [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] - public Type TryGetCSharpTypeForSQLDBType(string sqlType) + public Type? TryGetCSharpTypeForSQLDBType(string sqlType) { if (IsBit(sqlType)) return typeof(bool); @@ -310,7 +310,7 @@ public virtual int GetLengthIfString(string sqlType) return -1; } - public DecimalSize GetDigitsBeforeAndAfterDecimalPointIfDecimal(string sqlType) + public DecimalSize? GetDigitsBeforeAndAfterDecimalPointIfDecimal(string sqlType) { if (string.IsNullOrWhiteSpace(sqlType)) return null; diff --git a/FAnsiSql/FAnsi.csproj b/FAnsiSql/FAnsi.csproj index 17eac26c..95ed0e70 100644 --- a/FAnsiSql/FAnsi.csproj +++ b/FAnsiSql/FAnsi.csproj @@ -34,7 +34,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -42,10 +42,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs index 797fc7ac..6a7f109f 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs @@ -87,12 +87,12 @@ 3617 when string.IsNullOrWhiteSpace(sqlE.Message) => true, /// /// /// - private string GetRuntimeNameWithDoubledClosingSquareBrackets(string s) => GetRuntimeName(s)?.Replace("]","]]"); + private string? GetRuntimeNameWithDoubledClosingSquareBrackets(string s) => GetRuntimeName(s)?.Replace("]","]]"); - public override string EnsureFullyQualified(string databaseName, string schema, string tableName) + public override string EnsureFullyQualified(string databaseName, string? schema, string tableName) { //if there is no schema address it as db..table (which is the same as db.dbo.table in Microsoft SQL Server) - if(string.IsNullOrWhiteSpace(schema)) + if (string.IsNullOrWhiteSpace(schema)) return EnsureWrapped( GetRuntimeName(databaseName)) + DatabaseTableSeparator + DatabaseTableSeparator + EnsureWrapped(GetRuntimeName(tableName)); //there is a schema so add it in diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs index 1a0cb5ad..8451aa89 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs @@ -163,17 +163,17 @@ public override Dictionary DescribeDatabase(DbConnectionStringBu using (var da = new SqlDataAdapter(cmd)) da.Fill(ds); - toReturn.Add(ds.Tables[0].Columns[0].ColumnName, ds.Tables[0].Rows[0][0].ToString()); - toReturn.Add(ds.Tables[0].Columns[1].ColumnName, ds.Tables[1].Rows[0][1].ToString()); + toReturn.Add(ds.Tables[0].Columns[0].ColumnName, ds.Tables[0].Rows[0][0].ToString() ?? string.Empty); + toReturn.Add(ds.Tables[0].Columns[1].ColumnName, ds.Tables[1].Rows[0][1].ToString() ?? string.Empty); - toReturn.Add(ds.Tables[1].Columns[0].ColumnName, ds.Tables[1].Rows[0][0].ToString()); - toReturn.Add(ds.Tables[1].Columns[1].ColumnName, ds.Tables[1].Rows[0][1].ToString()); - toReturn.Add(ds.Tables[1].Columns[2].ColumnName, ds.Tables[1].Rows[0][2].ToString()); + toReturn.Add(ds.Tables[1].Columns[0].ColumnName, ds.Tables[1].Rows[0][0].ToString() ?? string.Empty); + toReturn.Add(ds.Tables[1].Columns[1].ColumnName, ds.Tables[1].Rows[0][1].ToString() ?? string.Empty); + toReturn.Add(ds.Tables[1].Columns[2].ColumnName, ds.Tables[1].Rows[0][2].ToString() ?? string.Empty); return toReturn; } - public override DirectoryInfo Detach(DiscoveredDatabase database) + public override DirectoryInfo? Detach(DiscoveredDatabase database) { const string getDefaultSqlServerDatabaseDirectory = """ SELECT LEFT(physical_name,LEN(physical_name)-CHARINDEX('\',REVERSE(physical_name))+1) @@ -233,7 +233,7 @@ public override void CreateBackup(DiscoveredDatabase discoveredDatabase,string b cmd.ExecuteNonQuery(); } - public override void CreateSchema(DiscoveredDatabase discoveredDatabase, string name) + public override void CreateSchema(DiscoveredDatabase discoveredDatabase, string? name) { var syntax = discoveredDatabase.Server.GetQuerySyntaxHelper(); var runtimeName = syntax.GetRuntimeName(name); diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs index c7b9c836..353ee7a5 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs @@ -67,7 +67,7 @@ public override DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTab /// /// /// - private static string GetObjectName(DiscoveredTable table) + private static string? GetObjectName(DiscoveredTable table) { var syntax = table.GetQuerySyntaxHelper(); @@ -80,7 +80,6 @@ private static string GetObjectName(DiscoveredTable table) public override void DropTable(DbConnection connection, DiscoveredTable tableToDrop) { - SqlCommand cmd; switch (tableToDrop.TableType) @@ -89,7 +88,7 @@ public override void DropTable(DbConnection connection, DiscoveredTable tableToD if (connection.Database != tableToDrop.Database.GetRuntimeName()) connection.ChangeDatabase(tableToDrop.GetRuntimeName()); - if(!connection.Database.ToLower().Equals(tableToDrop.Database.GetRuntimeName().ToLower())) + if (!connection.Database.ToLower().Equals(tableToDrop.Database.GetRuntimeName().ToLower())) throw new NotSupportedException( $"Cannot drop view {tableToDrop} because it exists in database {tableToDrop.Database.GetRuntimeName()} while the current current database connection is pointed at database:{connection.Database} (use .ChangeDatabase on the connection first) - SQL Server does not support cross database view dropping"); @@ -105,7 +104,7 @@ public override void DropTable(DbConnection connection, DiscoveredTable tableToD throw new ArgumentOutOfRangeException(nameof(tableToDrop),$"Unknown table type {tableToDrop.TableType}"); } - using(cmd) + using (cmd) cmd.ExecuteNonQuery(); } diff --git a/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs b/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs index a86f492a..b6b1744f 100644 --- a/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs +++ b/FAnsiSql/Implementations/MySql/MySqlBulkCopy.cs @@ -69,7 +69,6 @@ public override int UploadImpl(DataTable dt) ourTrans?.Commit(); return affected; - } private string ConstructIndividualValue(string dataType, object value) @@ -91,7 +90,7 @@ private string ConstructIndividualValue(string dataType, object value) if(value == null || value == DBNull.Value) return "NULL"; - return ConstructIndividualValue(dataType, value.ToString()); + return ConstructIndividualValue(dataType, value.ToString()); } private string ConstructIndividualValue(string dataType, string value) diff --git a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs index 2e22f6f5..f59505ed 100644 --- a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs @@ -68,7 +68,6 @@ public override DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTab toAdd.DataType = new DiscoveredDataType(r, TrimIntDisplayValues(r["COLUMN_TYPE"].ToString()), toAdd); columns.Add(toAdd); - } r.Close(); @@ -76,7 +75,6 @@ public override DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTab return [.. columns]; - } private static bool YesNoToBool(object o) diff --git a/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs b/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs index 3c5f1b06..2b36ce31 100644 --- a/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs +++ b/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs @@ -52,7 +52,7 @@ public override int UploadImpl(DataTable dt) dateColumns.Add(dataColumn); break; case DbType.Boolean: - p.DbType = DbType.Int32; // JS 2023-05-11 special case since we don't have a true boolean type in Oracle, but use 0/1 instead + p.DbType = DbType.Int32; // JS 2023-05-11 special case since we don't have a true boolean type in Oracle, but use 0/1 instead break; } } diff --git a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs index 24f12a45..a88caf7d 100644 --- a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs @@ -123,7 +123,7 @@ public override void DropColumn(DbConnection connection, DiscoveredColumn column cmd.ExecuteNonQuery(); } - private string GetBasicTypeFromOracleType(DbDataReader r) + private static string GetBasicTypeFromOracleType(IDataRecord r) { int? precision = null; int? scale = null; @@ -146,14 +146,14 @@ private string GetBasicTypeFromOracleType(DbDataReader r) return "decimal"; if (dataLength == null) - throw new Exception( + throw new InvalidOperationException( $"Found Oracle NUMBER datatype with scale {(scale != null ? scale.ToString() : "DBNull.Value")} and precision {(precision != null ? precision.ToString() : "DBNull.Value")}, did not know what datatype to use to represent it"); return "double"; case "FLOAT": return "double"; default: - return r["DATA_TYPE"].ToString()?.ToLower(); + return r["DATA_TYPE"].ToString()?.ToLower() ?? throw new InvalidOperationException("Null DATA_TYPE in db"); } } diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs index 764982f1..c0124e1f 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs @@ -44,11 +44,11 @@ public override void CreateDatabase(DbConnectionStringBuilder builder, IHasRunti public override Dictionary DescribeServer(DbConnectionStringBuilder builder) => throw new NotImplementedException(); - public override string GetExplicitUsernameIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Username; + public override string? GetExplicitUsernameIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Username; - public override string GetExplicitPasswordIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Password; + public override string? GetExplicitPasswordIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Password; - public override Version GetVersion(DiscoveredServer server) + public override Version? GetVersion(DiscoveredServer server) { using var con = server.GetConnection(); con.Open(); diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs index 610f524d..6da45ac5 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs @@ -116,15 +116,14 @@ AND indisprimary return [.. toReturn]; } - private string GetSQLType_FromSpColumnsResult(DbDataReader r) + private static string GetSQLType_FromSpColumnsResult(DbDataReader r) { var columnType = r["data_type"] as string; var lengthQualifier = ""; - if (HasPrecisionAndScale(columnType)) + if (HasPrecisionAndScale(columnType ?? string.Empty)) lengthQualifier = $"({r["numeric_precision"]},{r["numeric_scale"]})"; - else - if (r["character_maximum_length"] != DBNull.Value) lengthQualifier = $"({Convert.ToInt32(r["character_maximum_length"])})"; + else if (r["character_maximum_length"] != DBNull.Value) lengthQualifier = $"({Convert.ToInt32(r["character_maximum_length"])})"; return columnType + lengthQualifier; } diff --git a/FAnsiSql/Naming/IHasRuntimeName.cs b/FAnsiSql/Naming/IHasRuntimeName.cs index 98b2d8fc..e3a15822 100644 --- a/FAnsiSql/Naming/IHasRuntimeName.cs +++ b/FAnsiSql/Naming/IHasRuntimeName.cs @@ -13,5 +13,5 @@ public interface IHasRuntimeName /// Returns the name of a table/column without qualifiers e.g. returns "Name" for the column "[MyDatabase]..[MyTable].[Name]" /// /// - string GetRuntimeName(); + string? GetRuntimeName(); } \ No newline at end of file diff --git a/Tests/FAnsiTests/FAnsiTests.csproj b/Tests/FAnsiTests/FAnsiTests.csproj index 3c425a5c..05297dc7 100644 --- a/Tests/FAnsiTests/FAnsiTests.csproj +++ b/Tests/FAnsiTests/FAnsiTests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Tests/FAnsiTests/Table/CreateTableTests.cs b/Tests/FAnsiTests/Table/CreateTableTests.cs index 3c9679af..ef725068 100644 --- a/Tests/FAnsiTests/Table/CreateTableTests.cs +++ b/Tests/FAnsiTests/Table/CreateTableTests.cs @@ -50,7 +50,6 @@ public void TestTableCreation(DatabaseType type) new DatabaseColumnRequest("dob", new DatabaseTypeRequest(typeof (DateTime)),false), new DatabaseColumnRequest("score", new DatabaseTypeRequest(typeof (decimal), null, new DecimalSize(5, 3))) //<- e.g. 12345.123 - ]); Assert.That(tbl.Exists()); From 034e1db008dbdb3c4c8b85787c0cfe66095d2257 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 1 Feb 2024 17:17:20 -0600 Subject: [PATCH 7/7] Update Packages.md Remove disused NUnit Analyzer from main package, only needed in test --- Packages.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Packages.md b/Packages.md index 2b4044a7..460c6b57 100644 --- a/Packages.md +++ b/Packages.md @@ -15,4 +15,3 @@ | Oracle.ManagedDataAccess.Core | Closed Source | [OTNLA](https://www.oracle.com/downloads/licenses/distribution-license.html) | Enables interaction with Oracle databases | | HIC.TypeGuesser | [GitHub](https://github.com/HicServices/TypeGuesser) | [MIT](https://opensource.org/licenses/MIT)| Allows picking system Types for untyped strings e.g. `"12.3"`| | | Npgsql | [GitHub](https://github.com/npgsql/npgsql) | [PostgreSQL](https://github.com/npgsql/npgsql/blob/dev/LICENSE)| Enables interaction with Postgres databases | | -| [NUnit.Analyzers](https://nunit.org/) |[GitHub](https://github.com/nunit/nunit.analyzers) | [MIT](https://opensource.org/licenses/MIT) | Unit testing support code |