From 7107c7b0f5be78531ba918c550215adc9f7888e0 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Wed, 16 Aug 2023 14:05:19 +0100 Subject: [PATCH] Bugfix/mysqltext (#212) * Use MySQL LONGTEXT not TEXT - avoid 64k size limit * Fix MySQL text mapping (should be longtext, wrong sizes being assumed) --- CHANGELOG.md | 3 +- FAnsiSql/Connections/IManagedTransaction.cs | 2 +- FAnsiSql/Connections/ManagedConnection.cs | 2 +- FAnsiSql/DatabaseOperationArgs.cs | 6 +- FAnsiSql/DatabaseType.cs | 2 +- FAnsiSql/Discovery/BulkCopy.cs | 14 ++-- .../ConnectionStringKeywordAccumulator.cs | 10 +-- .../Constraints/DiscoveredRelationship.cs | 2 +- .../RelationshipTopologicalSort.cs | 4 +- FAnsiSql/Discovery/DatabaseColumnRequest.cs | 4 +- FAnsiSql/Discovery/DiscoveredDataType.cs | 12 ++-- FAnsiSql/Discovery/DiscoveredDatabase.cs | 8 +-- .../Discovery/DiscoveredDatabaseHelper.cs | 18 ++--- FAnsiSql/Discovery/DiscoveredServer.cs | 10 +-- FAnsiSql/Discovery/DiscoveredServerHelper.cs | 10 +-- FAnsiSql/Discovery/DiscoveredTable.cs | 16 ++--- FAnsiSql/Discovery/DiscoveredTableHelper.cs | 2 +- .../DiscoveredTableValuedFunction.cs | 4 +- .../Discovery/IDiscoveredDatabaseHelper.cs | 4 +- FAnsiSql/Discovery/IDiscoveredServerHelper.cs | 6 +- FAnsiSql/Discovery/IDiscoveredTableHelper.cs | 8 +-- .../AggregateCustomLineCollection.cs | 2 +- .../Aggregation/AggregateHelper.cs | 2 +- .../Aggregation/IAggregateHelper.cs | 2 +- .../QuerySyntax/Aggregation/IQueryAxis.cs | 4 +- FAnsiSql/Discovery/QuerySyntax/CustomLine.cs | 4 +- .../QuerySyntax/IHasQuerySyntaxHelper.cs | 4 +- .../QuerySyntax/IQuerySyntaxHelper.cs | 24 +++---- .../QuerySyntax/Update/IUpdateHelper.cs | 4 +- FAnsiSql/Discovery/QuerySyntaxHelper.cs | 34 +++++----- .../TableCreation/CreateTableArgs.cs | 10 +-- .../TypeTranslation/ITypeTranslater.cs | 8 +-- .../TypeTranslation/TypeTranslater.cs | 34 +++++----- FAnsiSql/Extensions/DataColumnExtensions.cs | 2 +- .../Implementation/ImplementationManager.cs | 2 +- .../MicrosoftSQLAggregateHelper.cs | 16 ++--- .../MicrosoftQuerySyntaxHelper.cs | 10 +-- .../MicrosoftSQL/MicrosoftSQLBulkCopy.cs | 12 ++-- .../MicrosoftSQLDatabaseHelper.cs | 4 +- .../MicrosoftSQL/MicrosoftSQLServerHelper.cs | 4 +- .../MicrosoftSQL/MicrosoftSQLTableHelper.cs | 10 +-- .../MySql/Aggregation/MySqlAggregateHelper.cs | 54 +++++++-------- .../MySql/MySqlDatabaseHelper.cs | 2 +- .../MySql/MySqlQuerySyntaxHelper.cs | 2 +- .../MySql/MySqlServerHelper.cs | 4 +- .../Implementations/MySql/MySqlTableHelper.cs | 4 +- .../MySql/MySqlTypeTranslater.cs | 18 +++-- .../Aggregation/OracleAggregateHelper.cs | 2 +- .../Implementations/Oracle/OracleBulkCopy.cs | 2 +- .../Oracle/OracleDatabaseHelper.cs | 4 +- .../Oracle/OracleQuerySyntaxHelper.cs | 4 +- .../Oracle/OracleServerHelper.cs | 2 +- .../Oracle/OracleTableHelper.cs | 12 ++-- .../Oracle/OracleTypeTranslater.cs | 4 +- .../Aggregation/PostgreSqlAggregateHelper.cs | 2 +- .../PostgreSql/PostgreSqlBulkCopy.cs | 2 +- .../PostgreSql/PostgreSqlDatabaseHelper.cs | 8 +-- .../PostgreSql/PostgreSqlSyntaxHelper.cs | 6 +- .../PostgreSql/PostgreSqlTableHelper.cs | 6 +- .../Update/PostgreSqlUpdateHelper.cs | 2 +- FAnsiSql/Naming/IHasRuntimeName.cs | 4 +- .../Aggregation/AggregationTests.cs | 4 +- .../Aggregation/CalendarAggregationTests.cs | 24 +++---- .../CalendarWithPivotAggregationTests.cs | 4 +- Tests/FAnsiTests/All.cs | 2 +- Tests/FAnsiTests/CrossPlatformTests.cs | 66 +++++++++---------- Tests/FAnsiTests/DatabaseTests.cs | 8 +-- Tests/FAnsiTests/Examples.cs | 4 +- Tests/FAnsiTests/ManagedConnectionTests.cs | 6 +- Tests/FAnsiTests/PackageListIsCorrectTests.cs | 2 +- Tests/FAnsiTests/Properties/AssemblyInfo.cs | 4 +- .../Query/QuerySyntaxHelperDatabaseTests.cs | 2 +- .../Query/QuerySyntaxHelperTests.cs | 12 ++-- Tests/FAnsiTests/Server/ServerTests.cs | 4 +- Tests/FAnsiTests/Table/BadNamesTests.cs | 18 ++--- Tests/FAnsiTests/Table/BasicInsertTests.cs | 4 +- Tests/FAnsiTests/Table/BulkInsertTest.cs | 12 ++-- Tests/FAnsiTests/Table/CreateTableTests.cs | 10 +-- Tests/FAnsiTests/Table/ForeignKeyTests.cs | 4 +- Tests/FAnsiTests/Table/TopXTests.cs | 2 +- Tests/FAnsiTests/Table/UpdateTests.cs | 2 +- .../TypeTranslation/DatatypeComputerTests.cs | 6 +- .../TypeTranslation/TypeTranslaterTests.cs | 26 ++++---- 83 files changed, 360 insertions(+), 349 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfa926e2..e89aad82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -... +- Bugfix: MySQL text was erroneously capped at 64k (TEXT) instead of LONGTEXT (4GiB) + ## [3.1.0] - 2023-05-15 - Now targeting .Net 6 diff --git a/FAnsiSql/Connections/IManagedTransaction.cs b/FAnsiSql/Connections/IManagedTransaction.cs index 3a8b251c..6e72c741 100644 --- a/FAnsiSql/Connections/IManagedTransaction.cs +++ b/FAnsiSql/Connections/IManagedTransaction.cs @@ -3,7 +3,7 @@ namespace FAnsi.Connections; /// -/// Wrapper for DbTransaction that associates it with a specific DbConnection. Helps simplify calls to information +/// Wrapper for DbTransaction that associates it with a specific DbConnection. Helps simplify calls to information /// methods such as DiscoveredTable.GetRowCount etc during the middle of an ongoing database transaction /// public interface IManagedTransaction diff --git a/FAnsiSql/Connections/ManagedConnection.cs b/FAnsiSql/Connections/ManagedConnection.cs index 7308e62d..ac4cd620 100644 --- a/FAnsiSql/Connections/ManagedConnection.cs +++ b/FAnsiSql/Connections/ManagedConnection.cs @@ -19,7 +19,7 @@ public class ManagedConnection : IManagedConnection /// public bool CloseOnDispose { get; set; } - + internal ManagedConnection(DiscoveredServer discoveredServer, IManagedTransaction managedTransaction) { //get a new connection or use the existing one within the transaction diff --git a/FAnsiSql/DatabaseOperationArgs.cs b/FAnsiSql/DatabaseOperationArgs.cs index a6502c14..720517d8 100644 --- a/FAnsiSql/DatabaseOperationArgs.cs +++ b/FAnsiSql/DatabaseOperationArgs.cs @@ -22,7 +22,7 @@ public class DatabaseOperationArgs /// Time to allow to run before cancelling (this is db timeout and doesn't affect ) /// public int TimeoutInSeconds { get; set; } - + /// /// Optional, if provided all commands interacting with these args should cancel if the command was cancelled /// @@ -87,7 +87,7 @@ private T Execute(DbCommand cmd, Func> method) throw; } - if (!t.IsCompleted) + if (!t.IsCompleted) cmd.Cancel(); if (t.Exception == null) return t.Result; @@ -95,7 +95,7 @@ private T Execute(DbCommand cmd, Func> method) throw t.Exception.InnerExceptions[0]; throw t.Exception; } - + public void Fill(DbDataAdapter da, DbCommand cmd, DataTable dt) { Hydrate(cmd); diff --git a/FAnsiSql/DatabaseType.cs b/FAnsiSql/DatabaseType.cs index 5f86b17d..e4de8b88 100644 --- a/FAnsiSql/DatabaseType.cs +++ b/FAnsiSql/DatabaseType.cs @@ -11,7 +11,7 @@ public enum DatabaseType MicrosoftSQLServer, /// - /// My Sql database engine. + /// My Sql database engine. /// MySql, diff --git a/FAnsiSql/Discovery/BulkCopy.cs b/FAnsiSql/Discovery/BulkCopy.cs index ca4a2ad0..e77d3e04 100644 --- a/FAnsiSql/Discovery/BulkCopy.cs +++ b/FAnsiSql/Discovery/BulkCopy.cs @@ -29,7 +29,7 @@ public abstract class BulkCopy:IBulkCopy /// call to refresh this. /// protected DiscoveredColumn[] TargetTableColumns; - + /// /// When calling GetMapping if there are DataColumns in the input table that you are trying to bulk insert that are not matched /// in the destination table then the default behaviour is to throw a KeyNotFoundException. Set this to false to ignore that @@ -41,7 +41,7 @@ public abstract class BulkCopy:IBulkCopy /// 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 /// . @@ -126,7 +126,7 @@ protected void ConvertStringTypesToHardTypes(DataTable dt) decider = DateTimeDecider; DateTimeDecider.GuessDateFormat(dt.Rows.Cast().Take(500).Select(r=>r[kvp.Key] as string)); } - + foreach(DataRow dr in dt.Rows) { @@ -160,8 +160,8 @@ protected void ConvertStringTypesToHardTypes(DataTable dt) } /// - /// Returns a case insensitive mapping between columns in your DataTable that you are trying to upload and the columns that actually exist in the destination - /// table. + /// Returns a case insensitive mapping between columns in your DataTable that you are trying to upload and the columns that actually exist in the destination + /// table. /// This overload gives you a list of all unmatched destination columns, these should be given null/default automatically by your database API /// Throws if there are unmatched input columns unless is true. /// @@ -194,8 +194,8 @@ protected Dictionary GetMapping(IEnumerable - /// Returns a case insensitive mapping between columns in your DataTable that you are trying to upload and the columns that actually exist in the destination - /// table. + /// Returns a case insensitive mapping between columns in your DataTable that you are trying to upload and the columns that actually exist in the destination + /// table. /// Throws if there are unmatched input columns unless is true. /// /// diff --git a/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs b/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs index d28db905..90fed69f 100644 --- a/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs +++ b/FAnsiSql/Discovery/ConnectionStringDefaults/ConnectionStringKeywordAccumulator.cs @@ -7,7 +7,7 @@ namespace FAnsi.Discovery.ConnectionStringDefaults; /// -/// Gathers keywords for use in building connection strings for a given . Once created you can add keywords and then apply the template +/// Gathers keywords for use in building connection strings for a given . Once created you can add keywords and then apply the template /// to new novel connection strings (see ). /// /// Also handles connection string keyword aliases (where two words mean the same thing) @@ -33,7 +33,7 @@ public ConnectionStringKeywordAccumulator(DatabaseType databaseType) } /// - /// Adds a new connection string option (which must be compatible with ) + /// Adds a new connection string option (which must be compatible with ) /// /// /// @@ -44,12 +44,12 @@ public void AddOrUpdateKeyword(string keyword, string value, ConnectionStringKey if (collision != null) { - //if there is already a semantically equivalent keyword.... + //if there is already a semantically equivalent keyword.... //if it is of lower or equal priority if (_keywords[collision].Item2 <= priority) - _keywords[collision] = Tuple.Create(value, priority); //update it - + _keywords[collision] = Tuple.Create(value, priority); //update it + //either way don't record it as a new keyword return; } diff --git a/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs b/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs index 39a7bfa0..34f576c1 100644 --- a/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs +++ b/FAnsiSql/Discovery/Constraints/DiscoveredRelationship.cs @@ -26,7 +26,7 @@ public class DiscoveredRelationship public DiscoveredTable ForeignKeyTable { get; private set; } /// - /// Mapping of primary key column(s) in to foreign key column(s) in . If there are more than one entry + /// Mapping of primary key column(s) in to foreign key column(s) in . If there are more than one entry /// then the foreign key is a composite key. /// public Dictionary Keys { get; private set; } diff --git a/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs b/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs index 92d9ee04..79fcfe67 100644 --- a/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs +++ b/FAnsiSql/Discovery/Constraints/RelationshipTopologicalSort.cs @@ -7,7 +7,7 @@ namespace FAnsi.Discovery.Constraints; /// -/// Helps resolve a dependency order between a collection of tables with interlinking foreign key constraints. Implements Khan's algorithm. +/// Helps resolve a dependency order between a collection of tables with interlinking foreign key constraints. Implements Khan's algorithm. /// public class RelationshipTopologicalSort { @@ -42,7 +42,7 @@ public RelationshipTopologicalSort(IEnumerable tables) } /// - /// Topological Sorting (Kahn's algorithm) + /// Topological Sorting (Kahn's algorithm) /// /// https://en.wikipedia.org/wiki/Topological_sorting /// diff --git a/FAnsiSql/Discovery/DatabaseColumnRequest.cs b/FAnsiSql/Discovery/DatabaseColumnRequest.cs index 65f5703e..df9435dc 100644 --- a/FAnsiSql/Discovery/DatabaseColumnRequest.cs +++ b/FAnsiSql/Discovery/DatabaseColumnRequest.cs @@ -38,7 +38,7 @@ public class DatabaseColumnRequest:ISupplementalColumnInformation,IHasRuntimeNam public bool AllowNulls { get; set; } /// - /// True to include the column as part of the tables primary key + /// True to include the column as part of the tables primary key /// public bool IsPrimaryKey { get; set; } @@ -53,7 +53,7 @@ public class DatabaseColumnRequest:ISupplementalColumnInformation,IHasRuntimeNam public MandatoryScalarFunctions Default { get; set; } /// - /// Applies only if the is string based. Setting this will override the default collation and specify + /// Applies only if the is string based. Setting this will override the default collation and specify /// a specific collation. The value specified must be an installed collation supported by the DBMS /// public string Collation { get; set; } diff --git a/FAnsiSql/Discovery/DiscoveredDataType.cs b/FAnsiSql/Discovery/DiscoveredDataType.cs index 89c920a4..c5102a1e 100644 --- a/FAnsiSql/Discovery/DiscoveredDataType.cs +++ b/FAnsiSql/Discovery/DiscoveredDataType.cs @@ -13,7 +13,7 @@ namespace FAnsi.Discovery; /// public 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. @@ -91,7 +91,7 @@ public override string ToString() public void Resize(int newSize, IManagedTransaction managedTransaction = null) { var toReplace = GetLengthIfString(); - + if(newSize == toReplace) return; @@ -104,7 +104,7 @@ public void Resize(int newSize, IManagedTransaction managedTransaction = null) } /// - /// Creates and runs an ALTER TABLE statement which will increase the size of a decimal column to support larger Precision/Scale values than it currently does. + /// Creates and runs an ALTER TABLE statement which will increase the size of a decimal column to support larger Precision/Scale values than it currently does. /// If you want decimal(4,2) then pass =2 and =2 /// /// Throws if the column is not a decimal type or the new size is smaller than the current column size @@ -126,11 +126,11 @@ 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))); - + AlterTypeTo(newDataType, managedTransaction); } @@ -164,7 +164,7 @@ public void AlterTypeTo(string newType, IManagedTransaction managedTransaction = } } - SQLType = newType; + SQLType = newType; } /// diff --git a/FAnsiSql/Discovery/DiscoveredDatabase.cs b/FAnsiSql/Discovery/DiscoveredDatabase.cs index 4df35b6a..39d3efda 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabase.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabase.cs @@ -73,7 +73,7 @@ public IEnumerable DiscoverTableValuedFunctions(I Helper.ListTableValuedFunctions(this, _querySyntaxHelper, managedConnection.Connection, GetRuntimeName(), managedConnection.Transaction).ToArray(); } - + /// /// Returns the name of the database without any qualifiers /// @@ -82,7 +82,7 @@ public string GetRuntimeName() { return _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]"). /// @@ -250,7 +250,7 @@ public DiscoveredTable CreateTable(CreateTableArgs args) } /// - /// Creates a table in the database big enough to store the supplied DataTable with appropriate types. + /// Creates a table in the database big enough to store the supplied DataTable with appropriate types. /// /// The computers used to determine column types /// @@ -275,7 +275,7 @@ public DiscoveredTable CreateTable(out Dictionary typeDictionar return table; } - + /// /// Creates a new schema within the database if the DBMS supports it (Sql Server does, MySql doesn't) and it does not already exist. Schema diff --git a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs index 3d5d56dd..2e521deb 100644 --- a/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredDatabaseHelper.cs @@ -16,7 +16,7 @@ namespace FAnsi.Discovery; /// -/// DBMS specific implementation of all functionality that relates to interacting with existing databases (dropping databases, creating tables, finding stored proceedures etc). For +/// DBMS specific implementation of all functionality that relates to interacting with existing databases (dropping databases, creating tables, finding stored proceedures etc). For /// database creation see /// public abstract class DiscoveredDatabaseHelper:IDiscoveredDatabaseHelper @@ -60,17 +60,17 @@ 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)) { //Type is for an explicit SQL Type e.g. varchar(5) - //Translate the sql type to a FAnsi type definition + //Translate the sql type to a FAnsi type definition var tt = args.Database.Server.GetQuerySyntaxHelper().TypeTranslater; request = tt.GetDataTypeRequestForSQLDBType(overriding.ExplicitDbType); - + } else throw new Exception(string.Format(FAnsiStrings.DiscoveredDatabaseHelper_CreateTable_DatabaseColumnRequestMustHaveEitherTypeRequestedOrExplicitDbType, column)); @@ -84,15 +84,15 @@ public DiscoveredTable CreateTable(CreateTableArgs args) //no, work out the column definition using a guesser var guesser = GetGuesser(column); guesser.Culture = args.Culture; - + CopySettings(guesser,args); guesser.AdjustToCompensateForValues(column); - + //if DoNotRetype is set on the column adjust the requested CSharpType to be the original type if (column.GetDoNotReType()) guesser.Guess.CSharpType = column.DataType; - + typeDictionary.Add(column.ColumnName,guesser); columns.Add(new DatabaseColumnRequest(column.ColumnName, guesser.Guess, column.AllowDBNull) { IsPrimaryKey = args.DataTable.PrimaryKey.Contains(column)}); @@ -202,7 +202,7 @@ public virtual string GetCreateTableSql(DiscoveredDatabase database, string tabl foreach (var col in columns) { var datatype = col.GetSQLDbType(syntaxHelper.TypeTranslater); - + //add the column name and accompanying datatype bodySql.AppendLine($"{GetCreateTableSqlLineForColumn(col, datatype, syntaxHelper)},"); } @@ -278,7 +278,7 @@ private string MakeSensibleConstraintName(string prefix, string tableName) return $"{prefix}{constraintName}"; } - + 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 acfff8fa..c5bfe30d 100644 --- a/FAnsiSql/Discovery/DiscoveredServer.cs +++ b/FAnsiSql/Discovery/DiscoveredServer.cs @@ -149,7 +149,7 @@ private DbParameter GetParameter(string parameterName) } /// - /// Returns a new of the correct of the server. Also adds it + /// Returns a new of the correct of the server. Also adds it /// to the of and sets it's /// /// @@ -297,10 +297,10 @@ public DiscoveredDatabase GetCurrentDatabase() //no (e.g. Oracle or no default database specified in connection string) return _currentDatabase; //yes use that one } - + /// - /// Edits the connection string (See ) to allow async operations. Depending on DBMS this may have - /// no effect (e.g. Sql Server needs AsynchronousProcessing and MultipleActiveResultSets but Oracle / MySql do not need + /// Edits the connection string (See ) to allow async operations. Depending on DBMS this may have + /// no effect (e.g. Sql Server needs AsynchronousProcessing and MultipleActiveResultSets but Oracle / MySql do not need /// any special keywords) /// public void EnableAsync() @@ -383,7 +383,7 @@ public IQuerySyntaxHelper GetQuerySyntaxHelper() { return Helper.GetQuerySyntaxHelper(); } - + /// /// Return key value pairs which describe attributes of the server e.g. version, available drive space etc /// diff --git a/FAnsiSql/Discovery/DiscoveredServerHelper.cs b/FAnsiSql/Discovery/DiscoveredServerHelper.cs index 5c6753f2..f3faa283 100644 --- a/FAnsiSql/Discovery/DiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredServerHelper.cs @@ -31,7 +31,7 @@ public static void AddConnectionStringKeyword(DatabaseType databaseType, string ConnectionStringKeywordAccumulators[databaseType].AddOrUpdateKeyword(keyword,value,priority); } - + /// public abstract DbCommand GetCommand(string s, DbConnection con, DbTransaction transaction = null); @@ -43,7 +43,7 @@ public static void AddConnectionStringKeyword(DatabaseType databaseType, string /// public abstract DbParameter GetParameter(string parameterName); - + public abstract DbConnection GetConnection(DbConnectionStringBuilder builder); public DbConnectionStringBuilder GetConnectionStringBuilder(string connectionString) @@ -53,7 +53,7 @@ public DbConnectionStringBuilder GetConnectionStringBuilder(string connectionStr return builder; } - + /// public DbConnectionStringBuilder GetConnectionStringBuilder(string server, string database, string username, string password) { @@ -76,8 +76,8 @@ protected virtual void EnforceKeywords(DbConnectionStringBuilder builder) } protected abstract DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString, string database, string username, string password); protected abstract DbConnectionStringBuilder GetConnectionStringBuilderImpl(string connectionString); - - + + protected abstract string ServerKeyName { get; } protected abstract string DatabaseKeyName { get; } diff --git a/FAnsiSql/Discovery/DiscoveredTable.cs b/FAnsiSql/Discovery/DiscoveredTable.cs index a2d0237b..416cf47a 100644 --- a/FAnsiSql/Discovery/DiscoveredTable.cs +++ b/FAnsiSql/Discovery/DiscoveredTable.cs @@ -68,7 +68,7 @@ public DiscoveredTable(DiscoveredDatabase database, string table, IQuerySyntaxHe QuerySyntaxHelper.ValidateTableName(_table); } - + /// /// Checks that the exists then lists the tables in the database to confirm this table exists on the server /// @@ -101,7 +101,7 @@ public virtual string GetFullyQualifiedName() { return 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. /// @@ -142,7 +142,7 @@ public IQuerySyntaxHelper GetQuerySyntaxHelper() /// /// Returns from the on the server. This is not not case sensitive. Requires - /// connecting to the database. + /// connecting to the database. /// /// The column you want to find /// Optional - if set the connection to list tables will be sent on the connection on which the current @@ -198,9 +198,9 @@ public DataTable GetDataTable(DatabaseOperationArgs args,int topX = int.MaxValue return dt; } - + /// - /// Drops (deletes) the table from the database. This is irreversible unless you have a database backup. + /// Drops (deletes) the table from the database. This is irreversible unless you have a database backup. /// public virtual void Drop() { @@ -223,7 +223,7 @@ public int GetRowCount(DatabaseOperationArgs args) { return Helper.GetRowCount(args, this); } - + /// /// Returns true if there are no rows in the table /// @@ -294,7 +294,7 @@ public void DropColumn(DiscoveredColumn column) using var connection = Database.Server.GetManagedConnection(); Helper.DropColumn(connection.Connection, column); } - + /// /// Creates a new object for bulk inserting records into the table. You should use a using block since is . /// Depending on implementation, records may not be committed to the server until the is disposed. @@ -411,7 +411,7 @@ public void CreatePrimaryKey(IManagedTransaction transaction ,CancellationToken }, this, discoverColumns); } - + public void CreatePrimaryKey(DatabaseOperationArgs args, params DiscoveredColumn[] discoverColumns) { Helper.CreatePrimaryKey(args,this, discoverColumns); diff --git a/FAnsiSql/Discovery/DiscoveredTableHelper.cs b/FAnsiSql/Discovery/DiscoveredTableHelper.cs index 874c67c4..d6b92fdb 100644 --- a/FAnsiSql/Discovery/DiscoveredTableHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredTableHelper.cs @@ -20,7 +20,7 @@ public abstract class DiscoveredTableHelper :IDiscoveredTableHelper public abstract string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int topX); public abstract DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTable, IManagedConnection connection, string database); - + public abstract IDiscoveredColumnHelper GetColumnHelper(); public virtual void DropTable(DbConnection connection, DiscoveredTable tableToDrop) { diff --git a/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs b/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs index 47315c84..9c32fd97 100644 --- a/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs +++ b/FAnsiSql/Discovery/DiscoveredTableValuedFunction.cs @@ -12,7 +12,7 @@ namespace FAnsi.Discovery; public class DiscoveredTableValuedFunction : DiscoveredTable { private readonly string _functionName; - + //constructor public DiscoveredTableValuedFunction(DiscoveredDatabase database, string functionName, IQuerySyntaxHelper querySyntaxHelper, string schema = null) : base(database, functionName, querySyntaxHelper, @@ -36,7 +36,7 @@ public override string GetFullyQualifiedName() //Note that we do not give the parameters values, the client must decide appropriate values and put them in correspondingly named variables return $"{Database.GetRuntimeName()}..{GetRuntimeName()}({parameters})"; } - + public override string ToString() => _functionName; public override void Drop() diff --git a/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs b/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs index 757d8e58..24939e4c 100644 --- a/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredDatabaseHelper.cs @@ -26,7 +26,7 @@ public interface IDiscoveredDatabaseHelper Dictionary DescribeDatabase(DbConnectionStringBuilder builder, string database); DiscoveredTable CreateTable(CreateTableArgs args); - + string GetCreateTableSql(DiscoveredDatabase database, string tableName, DatabaseColumnRequest[] columns, Dictionary foreignKeyPairs, bool cascadeDelete,string schema = null); /// @@ -47,7 +47,7 @@ string GetForeignKeyConstraintSql(string foreignTable, IQuerySyntaxHelper syntax DirectoryInfo Detach(DiscoveredDatabase database); void CreateBackup(DiscoveredDatabase discoveredDatabase, string backupName); - + /// /// Gets a sensible name for a foreign key constraint between the two tables /// diff --git a/FAnsiSql/Discovery/IDiscoveredServerHelper.cs b/FAnsiSql/Discovery/IDiscoveredServerHelper.cs index 2a9745b6..ece65f91 100644 --- a/FAnsiSql/Discovery/IDiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredServerHelper.cs @@ -21,9 +21,9 @@ public interface IDiscoveredServerHelper DbConnection GetConnection(DbConnectionStringBuilder builder); DbConnectionStringBuilder GetConnectionStringBuilder(string connectionString); - + /// - /// Returns a new connection string builder with the supplied parameters. Note that if a concept is not supported in the + /// Returns a new connection string builder with the supplied parameters. Note that if a concept is not supported in the /// implementation then the value will not appear in the connection string (e.g. Oracle /// does not support specifying a to connect to). /// @@ -54,7 +54,7 @@ public interface IDiscoveredServerHelper DatabaseType DatabaseType { get; } 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); diff --git a/FAnsiSql/Discovery/IDiscoveredTableHelper.cs b/FAnsiSql/Discovery/IDiscoveredTableHelper.cs index bc995d52..f4c96679 100644 --- a/FAnsiSql/Discovery/IDiscoveredTableHelper.cs +++ b/FAnsiSql/Discovery/IDiscoveredTableHelper.cs @@ -20,7 +20,7 @@ public interface IDiscoveredTableHelper DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTable, IManagedConnection connection, string database); IDiscoveredColumnHelper GetColumnHelper(); - + void DropTable(DbConnection connection, DiscoveredTable tableToDrop); void DropFunction(DbConnection connection, DiscoveredTableValuedFunction functionToDrop); void DropColumn(DbConnection connection, DiscoveredColumn columnToDrop); @@ -32,7 +32,7 @@ public interface IDiscoveredTableHelper IEnumerable DiscoverTableValuedFunctionParameters(DbConnection connection, DiscoveredTableValuedFunction discoveredTableValuedFunction, DbTransaction transaction); IBulkCopy BeginBulkInsert(DiscoveredTable discoveredTable, IManagedConnection connection,CultureInfo culture); - + void TruncateTable(DiscoveredTable discoveredTable); void MakeDistinct(DatabaseOperationArgs args,DiscoveredTable discoveredTable); @@ -44,8 +44,8 @@ public interface IDiscoveredTableHelper 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); - - + + /// /// Creates a new primary key relationship in a foreign key table that points to a primary key table (which must have a primary key) /// diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs index 0c2b82e1..5f54ff05 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateCustomLineCollection.cs @@ -36,7 +36,7 @@ private void Validate() /// The single aggregate function line e.g. "count(distinct chi) as Fish," /// public CustomLine CountSelect => Lines.SingleOrDefault(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," /// diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs index e393658c..8b5bb07e 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/AggregateHelper.cs @@ -47,7 +47,7 @@ private CustomLine GetPivotOnlyNonPivotColumn(AggregateCustomLineCollection quer /// /// protected abstract string BuildAxisAggregate(AggregateCustomLineCollection query); - + protected abstract string BuildPivotOnlyAggregate(AggregateCustomLineCollection query,CustomLine nonPivotColumn); protected abstract string BuildPivotAndAxisAggregate(AggregateCustomLineCollection query); diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs index b0f6acdb..25738c45 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/IAggregateHelper.cs @@ -3,7 +3,7 @@ namespace FAnsi.Discovery.QuerySyntax.Aggregation; /// -/// Cross Database Type class for turning a collection of arbitrary sql lines (CustomLine) into a Group by query. The query can include an axis calendar +/// Cross Database Type class for turning a collection of arbitrary sql lines (CustomLine) into a Group by query. The query can include an axis calendar /// table and can include a dynamic pivot. See AggregateDataBasedTests for expected inputs/outputs. /// /// Because building a dynamic pivot / calendar table for a group by is so different in each DatabaseType the input is basically just a collection of strings diff --git a/FAnsiSql/Discovery/QuerySyntax/Aggregation/IQueryAxis.cs b/FAnsiSql/Discovery/QuerySyntax/Aggregation/IQueryAxis.cs index 2cce5b25..742a7739 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Aggregation/IQueryAxis.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Aggregation/IQueryAxis.cs @@ -2,9 +2,9 @@ namespace FAnsi.Discovery.QuerySyntax.Aggregation; /// /// Describes the requirement for a Calendar Table in a Group By query. The calendar should go between the two dates in increments of the AxisIncrement. -/// Records returned by the Group By query should be grouped by the Calendar table. +/// Records returned by the Group By query should be grouped by the Calendar table. /// -/// A Calendar Table ensures a consistent axis in the DataTable returned by the sql query (avoids skipping months/years where there are no dates in the +/// A Calendar Table ensures a consistent axis in the DataTable returned by the sql query (avoids skipping months/years where there are no dates in the /// data set being queried). Implementation logic for Calendar Tables varies wildly depending on database engine (See IAggregateHelper). /// public interface IQueryAxis diff --git a/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs b/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs index 8feb2885..967c8031 100644 --- a/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs +++ b/FAnsiSql/Discovery/QuerySyntax/CustomLine.cs @@ -18,9 +18,9 @@ public class CustomLine public QueryComponent LocationToInsert { get; set; } public CustomLineRole Role { get; set; } - + /// - /// The line of code that caused the CustomLine to be created, this can be a StackTrace passed into the constructor or calculated automatically by CustomLine + /// The line of code that caused the CustomLine to be created, this can be a StackTrace passed into the constructor or calculated automatically by CustomLine /// public string StackTrace { get; private set; } diff --git a/FAnsiSql/Discovery/QuerySyntax/IHasQuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntax/IHasQuerySyntaxHelper.cs index 78c04927..5a2940b6 100644 --- a/FAnsiSql/Discovery/QuerySyntax/IHasQuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/IHasQuerySyntaxHelper.cs @@ -1,8 +1,8 @@ namespace FAnsi.Discovery.QuerySyntax; /// -/// Object which works with a known DatabaseType and therefore has an associated IQuerySyntaxHelper (e.g. DatabaseType.MicrosoftSQLServer and -/// MicrosoftQuerySyntaxHelper). +/// Object which works with a known DatabaseType and therefore has an associated IQuerySyntaxHelper (e.g. DatabaseType.MicrosoftSQLServer and +/// MicrosoftQuerySyntaxHelper). /// /// When implementing this class you most likely want to start with 'new QuerySyntaxHelperFactory().Create(DatabaseType);' /// diff --git a/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs index 69186f8e..f181f425 100644 --- a/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/IQuerySyntaxHelper.cs @@ -11,10 +11,10 @@ namespace FAnsi.Discovery.QuerySyntax; /// /// Cross database type functionality for helping build SQL commands that will work regardless of DatabaseType (Microsoft Sql Server / MySql etc). Describes -/// how to translate broad requirements like 'database type capable of storing strings up to 10 characters long' into a specific implementation e.g. +/// how to translate broad requirements like 'database type capable of storing strings up to 10 characters long' into a specific implementation e.g. /// 'varchar(10)' in Microsoft SQL Server and 'varchar2(10)' in Oracle (See ITypeTranslater). /// -/// Also includes features such as qualifying database entities [MyDatabase]..[MyTable].[MyColumn] in Sql Server vs `MyDatabase`.`MyTable`.`MyColumn` in +/// Also includes features such as qualifying database entities [MyDatabase]..[MyTable].[MyColumn] in Sql Server vs `MyDatabase`.`MyTable`.`MyColumn` in /// MySql. /// /// Also includes methods for dealing with no n Ansi standard functionality e.g. TOP X , MD5 etc @@ -36,7 +36,7 @@ public interface IQuerySyntaxHelper IAggregateHelper AggregateHelper { get; } IUpdateHelper UpdateHelper { get; set; } - + /// /// The character that is used to qualify database entity names e.g. "[" for "[My Table]" /// @@ -80,7 +80,7 @@ public interface IQuerySyntaxHelper 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. /// @@ -91,11 +91,11 @@ public interface IQuerySyntaxHelper TopXResponse HowDoWeAchieveTopX(int x); string GetParameterDeclaration(string proposedNewParameterName, DatabaseTypeRequest request); string GetParameterDeclaration(string proposedNewParameterName, string sqlType); - + bool IsValidParameterName(string parameterSQL); string AliasPrefix { get; } - + /// /// The maximum number of characters allowed in database names according to the DBMS /// @@ -142,7 +142,7 @@ public interface IQuerySyntaxHelper bool IsBasicallyNull(object value); bool IsTimeout(Exception exception); - + HashSet GetReservedWords(); /// @@ -155,7 +155,7 @@ public interface IQuerySyntaxHelper /// /// Gets a DbParameter hard typed with the correct DbType for the discoveredColumn and the Value set to the correct Value representation (e.g. DBNull for nulls or whitespace). - /// Also handles converting DateTime representations since many DBMS are a bit rubbish at that + /// Also handles converting DateTime representations since many DBMS are a bit rubbish at that /// /// /// The column the parameter is for loading - this is used to determine the DbType for the paramter @@ -165,7 +165,7 @@ public interface IQuerySyntaxHelper /// /// Gets a DbParameter hard typed with the correct DbType for the discoveredColumn and the Value set to the correct Value representation (e.g. DBNull for nulls or whitespace). - /// Also handles converting DateTime representations since many DBMS are a bit rubbish at that + /// Also handles converting DateTime representations since many DBMS are a bit rubbish at that /// /// /// The column the parameter is for loading - this is used to determine the DbType for the paramter @@ -189,7 +189,7 @@ public interface IQuerySyntaxHelper /// Throws if the supplied name is invalid (because it is too long or contains unsupported characters) /// void ValidateColumnName(string columnName); - + /// /// Returns false if the supplied name is invalid (because it is too long or contains unsupported characters) /// @@ -222,12 +222,12 @@ public enum MandatoryScalarFunctions /// A scalar function which must return todays datetime. Must be valid as a column default too /// GetTodaysDate, - + /// /// A scalar function which must return a new random GUID. /// GetGuid, - + /// /// A scalar function which must take a single argument (column name) and return the length of values in it /// diff --git a/FAnsiSql/Discovery/QuerySyntax/Update/IUpdateHelper.cs b/FAnsiSql/Discovery/QuerySyntax/Update/IUpdateHelper.cs index 92a142ae..d91fec61 100644 --- a/FAnsiSql/Discovery/QuerySyntax/Update/IUpdateHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntax/Update/IUpdateHelper.cs @@ -5,7 +5,7 @@ namespace FAnsi.Discovery.QuerySyntax.Update; public delegate string UpdateStatementSqlGetter(string table2Alias); /// -/// Cross Database Type class for turning a collection of arbitrary sql lines (CustomLine) into an UPDATE query where no suitable ANSI solution exists. For example +/// Cross Database Type class for turning a collection of arbitrary sql lines (CustomLine) into an UPDATE query where no suitable ANSI solution exists. For example /// updating a table using a join to another table where the relationship is n..n. /// /// Look at UpdateHelper.permissableLocations to determine which CustomLines you are allowed to pass in. @@ -20,7 +20,7 @@ public interface IUpdateHelper /// The table to UPDATE /// The table to join against (which might be a self join) /// All SET, WHERE and JoinInfo lines needed to build the query, columns should be specified using the alias t1.colX and t2.colY instead of the full names of - /// table1/table2. if you have multiple WHERE lines then they will be ANDed. To avoid this you can concatenate your CustomLines together yourself and serve only one to this + /// table1/table2. if you have multiple WHERE lines then they will be ANDed. To avoid this you can concatenate your CustomLines together yourself and serve only one to this /// method(e.g. to use OR) /// string BuildUpdate(DiscoveredTable table1, DiscoveredTable table2,List lines); diff --git a/FAnsiSql/Discovery/QuerySyntaxHelper.cs b/FAnsiSql/Discovery/QuerySyntaxHelper.cs index 2ed7d275..7f717f44 100644 --- a/FAnsiSql/Discovery/QuerySyntaxHelper.cs +++ b/FAnsiSql/Discovery/QuerySyntaxHelper.cs @@ -18,7 +18,7 @@ namespace FAnsi.Discovery; public abstract class QuerySyntaxHelper : IQuerySyntaxHelper { public virtual string DatabaseTableSeparator => "."; - + /// public abstract int MaximumDatabaseLength { get; } @@ -27,7 +27,7 @@ public abstract class QuerySyntaxHelper : IQuerySyntaxHelper /// public abstract int MaximumColumnLength { get; } - + /// public virtual char[] IllegalNameChars { get; } = {'.','(',')'}; @@ -44,12 +44,12 @@ public abstract class QuerySyntaxHelper : IQuerySyntaxHelper /// public abstract string OpenQualifier {get;} - + /// public abstract string CloseQualifier {get;} public ITypeTranslater TypeTranslater { get; private set; } - + private readonly Dictionary factories = new(); public IAggregateHelper AggregateHelper { get; private set; } @@ -81,14 +81,14 @@ protected string GetAliasConst() { return " AS "; } - + public string AliasPrefix => GetAliasConst(); //Only look at the start of the string or following an equals or white space and stop at word boundaries private static readonly Regex ParameterNameRegex = new ($@"(?:^|[\s+\-*/\\=(,])+{ParameterNamesRegex}\b"); /// - /// Lists the names of all parameters required by the supplied whereSql e.g. @bob = 'bob' would return "@bob" + /// Lists the names of all parameters required by the supplied whereSql e.g. @bob = 'bob' would return "@bob" /// /// the SQL you want to determine the parameter names in /// parameter names that are required by the SQL @@ -122,7 +122,7 @@ protected QuerySyntaxHelper(ITypeTranslater translater, IAggregateHelper aggrega DatabaseType = databaseType; } - + public virtual string GetRuntimeName(string s) { if (string.IsNullOrWhiteSpace(s)) @@ -219,7 +219,7 @@ public virtual HashSet GetReservedWords() public abstract string GetParameterDeclaration(string proposedNewParameterName, string sqlType); /// - /// Splits the given into + /// Splits the given into /// /// /// @@ -303,7 +303,7 @@ public static string MakeHeaderNameSensible(string header) 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 + 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]); } @@ -357,15 +357,15 @@ public virtual bool IsTimeout(Exception exception) } public abstract string HowDoWeAchieveMd5(string selectSql); - - + + 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)); @@ -376,7 +376,7 @@ 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 + 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); @@ -391,7 +391,7 @@ public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn { o = FormatTimespanForDbParameter(t); } - + p.Value = o; @@ -428,7 +428,7 @@ public bool IsValidDatabaseName(string databaseName,out string reason) reason = ValidateName(databaseName, "Database", MaximumDatabaseLength); return string.IsNullOrWhiteSpace(reason); } - + public bool IsValidTableName(string tableName,out string reason) { reason = ValidateName(tableName, "Table", MaximumTableLength); @@ -470,7 +470,7 @@ private string ValidateName(string candidate, string objectType, int maximumLeng return null; } - + public DbParameter GetParameter(DbParameter p, DiscoveredColumn discoveredColumn, object value) { @@ -539,7 +539,7 @@ public Dictionary GetParameterNamesFor(T[] columns, Func { var c = columns[i]; var columnName = toStringFunc(c); - + if(!sensibleParameterNamesInclude.IsMatch(columnName)) //if column name is "_:_" or something toReturn.Add(c, $"{ParameterSymbol}p{i}"); else diff --git a/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs b/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs index a9d86fde..d9ca5533 100644 --- a/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs +++ b/FAnsiSql/Discovery/TableCreation/CreateTableArgs.cs @@ -67,7 +67,7 @@ public class CreateTableArgs public bool TableCreated { get; private set; } /// - /// Customise guessing behaviour + /// Customise guessing behaviour /// public GuessSettings GuessSettings { get; set; } @@ -92,7 +92,7 @@ public CreateTableArgs(DiscoveredDatabase database, string tableName, string sch Schema = schema; GuessSettings = GuessSettingsFactory.Create(); } - + /// /// Create a table with the given name. Set your columns in /// @@ -104,7 +104,7 @@ 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 + /// 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) @@ -113,9 +113,9 @@ public CreateTableArgs(DiscoveredDatabase database, string tableName, string sch DataTable = dataTable; CreateEmpty = createEmpty; } - + /// - /// Create a table with the given name based on the columns and data in the provided . If you want to override the + /// 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, Dictionary foreignKeyPairs, bool cascadeDelete) diff --git a/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs b/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs index 8534e626..4fc655c3 100644 --- a/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs +++ b/FAnsiSql/Discovery/TypeTranslation/ITypeTranslater.cs @@ -6,7 +6,7 @@ namespace FAnsi.Discovery.TypeTranslation; /// /// Cross database type functionality for translating between database proprietary datatypes e.g. varchar (varchar2 in Oracle) and the C# Type (and vice -/// versa). +/// versa). /// /// When translating into a database type from a C# Type you also need to know additonal information e.g. how long is the maximum length of a string, how much /// scale/precision should a decimal have. This is represented by the DatabaseTypeRequest class. @@ -15,7 +15,7 @@ namespace FAnsi.Discovery.TypeTranslation; public interface ITypeTranslater { /// - /// DatabaseTypeRequest is turned into the proprietary string e.g. A DatabaseTypeRequest with CSharpType = typeof(DateTime) is translated into + /// DatabaseTypeRequest is turned into the proprietary string e.g. A DatabaseTypeRequest with CSharpType = typeof(DateTime) is translated into /// 'datetime2' in Microsoft SQL Server but 'datetime' in MySql server. /// /// @@ -37,7 +37,7 @@ public interface ITypeTranslater /// /// The C# Type which can be used to store values of this database type Type GetCSharpTypeForSQLDBType(string sqlType); - + /// /// Translates a database proprietary type e.g. 'decimal(10,2)' into a C# type e.g. 'typeof(decimal)' /// @@ -64,7 +64,7 @@ public interface ITypeTranslater int GetLengthIfString(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 /// e.g. Varchar2(10) if destinationTypeTranslater was Oracle. Even if both this and the destination are the same you might find a different datatype diff --git a/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs b/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs index 50d773e3..9b386e0f 100644 --- a/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs +++ b/FAnsiSql/Discovery/TypeTranslation/TypeTranslater.cs @@ -37,7 +37,7 @@ public abstract class TypeTranslater:ITypeTranslater /// use to determine the required length/type at runtime. /// private readonly int StringWidthWhenNotSupplied; - + /// /// /// @@ -58,13 +58,13 @@ public string GetSQLDBTypeForCSharpType(DatabaseTypeRequest request) if (t == typeof(byte)) return GetByteDataType(); - + if (t == typeof(short) || t == typeof(short) || t == typeof(ushort) || t == typeof(short?) || t == typeof(ushort?)) return GetSmallIntDataType(); if (t == typeof(int) || t == typeof(int) || t == typeof(uint) || t == typeof(int?) || t == typeof(uint?)) return GetIntDataType(); - + if (t == typeof (long) || t == typeof(ulong) || t == typeof(long?) || t == typeof(ulong?)) return GetBigIntDataType(); @@ -80,7 +80,7 @@ public string GetSQLDBTypeForCSharpType(DatabaseTypeRequest request) if (t == typeof(TimeSpan) || t == typeof(TimeSpan?)) return GetTimeDataType(); - + if (t == typeof (byte[])) return GetByteArrayDataType(); @@ -89,7 +89,7 @@ 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)); } - + protected string GetByteArrayDataType() { return "varbinary(max)"; @@ -120,7 +120,7 @@ protected string GetStringDataType(int? maxExpectedStringWidth) if (maxExpectedStringWidth > MaxStringWidthBeforeMax) return GetStringDataTypeWithUnlimitedWidth(); - + return GetStringDataTypeImpl(maxExpectedStringWidth.Value); } @@ -130,8 +130,8 @@ protected virtual string GetStringDataTypeImpl(int maxExpectedStringWidth) } public abstract string GetStringDataTypeWithUnlimitedWidth(); - - + + private string GetUnicodeStringDataType(int? maxExpectedStringWidth) { if (maxExpectedStringWidth == null) @@ -139,7 +139,7 @@ private string GetUnicodeStringDataType(int? maxExpectedStringWidth) if (maxExpectedStringWidth > MaxStringWidthBeforeMax) return GetUnicodeStringDataTypeWithUnlimitedWidth(); - + return GetUnicodeStringDataTypeImpl(maxExpectedStringWidth.Value); } @@ -228,7 +228,7 @@ public Type TryGetCSharpTypeForSQLDBType(string sqlType) return null; } - + /// public bool IsSupportedSQLDBType(string sqlType) { @@ -259,13 +259,13 @@ public DbType GetDbTypeForSQLDBType(string sqlType) if (IsString(sqlType)) return DbType.String; - + if (IsDate(sqlType)) return DbType.DateTime; if (IsTime(sqlType)) return DbType.Time; - + if (IsByteArray(sqlType)) return DbType.Object; @@ -295,7 +295,7 @@ public virtual DatabaseTypeRequest GetDataTypeRequestForSQLDBType(string sqlType if (cSharpType == typeof(TimeSpan)) lengthIfString = GetStringLengthForTimeSpan(); - + var request = new DatabaseTypeRequest(cSharpType, lengthIfString, digits); if (cSharpType == typeof(string)) @@ -328,7 +328,7 @@ protected Guesser GetGuesserFor(DiscoveredColumn discoveredColumn, int extraLeng ExtraLengthPerNonAsciiCharacter = extraLengthPerNonAsciiCharacter }; } - + public virtual int GetLengthIfString(string sqlType) { if (string.IsNullOrWhiteSpace(sqlType)) @@ -374,11 +374,11 @@ public string TranslateSQLDBType(string sqlType, ITypeTranslater destinationType //this then returns datetime (e.g. mysql) return destinationTypeTranslater.GetSQLDBTypeForCSharpType(requested); } - + /// /// Return the number of characters required to not truncate/loose any data when altering a column from time (e.g. TIME etc) to varchar(x). Return - /// x such that the column does not loose integrity. This is needed when dynamically discovering what size to make a column by streaming data into a table. + /// x such that the column does not loose integrity. This is needed when dynamically discovering what size to make a column by streaming data into a table. /// if we see many times and nulls we will decide to use a time column then we see strings and have to convert the column to a varchar column without loosing the /// currently loaded data. /// @@ -409,7 +409,7 @@ select LEN(dt) from omgTimes /// /// 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 - /// x such that the column does not loose integrity. This is needed when dynamically discovering what size to make a column by streaming data into a table. + /// x such that the column does not loose integrity. This is needed when dynamically discovering what size to make a column by streaming data into a table. /// if we see many dates and nulls we will decide to use a date column then we see strings and have to convert the column to a varchar column without loosing the /// currently loaded data. /// diff --git a/FAnsiSql/Extensions/DataColumnExtensions.cs b/FAnsiSql/Extensions/DataColumnExtensions.cs index 94c98792..002ef8ad 100644 --- a/FAnsiSql/Extensions/DataColumnExtensions.cs +++ b/FAnsiSql/Extensions/DataColumnExtensions.cs @@ -35,7 +35,7 @@ public static void SetDoNotReType(this DataColumn dc, bool value) /// public static bool GetDoNotReType(this DataColumn dc) { - return + return dc.DataType == typeof(string) && dc.ExtendedProperties[DoNotReTypeExtendedProperty] is true; } diff --git a/FAnsiSql/Implementation/ImplementationManager.cs b/FAnsiSql/Implementation/ImplementationManager.cs index cdc03fda..1ec88d11 100644 --- a/FAnsiSql/Implementation/ImplementationManager.cs +++ b/FAnsiSql/Implementation/ImplementationManager.cs @@ -69,7 +69,7 @@ public static IImplementation GetImplementation(DbConnectionStringBuilder connec public static IImplementation GetImplementation(DbConnection connection) { - return GetImplementation(i => i.IsFor(connection), + return GetImplementation(i => i.IsFor(connection), string.Format( FAnsiStrings .ImplementationManager_GetImplementation_No_implementation_found_for_ADO_Net_object_of_Type__0_, diff --git a/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs index 841b775a..f8c0d90c 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/Aggregation/MicrosoftSQLAggregateHelper.cs @@ -9,10 +9,10 @@ public class MicrosoftSQLAggregateHelper : AggregateHelper { private string GetDateAxisTableDeclaration(IQueryAxis axis) { - //if pivot dimension is set then this code appears inside dynamic SQL constant string that will be Exec'd so we have to escape single quotes + //if pivot dimension is set then this code appears inside dynamic SQL constant string that will be Exec'd so we have to escape single quotes var startDateSql = axis.StartDate; var endDateSql = axis.EndDate; - + return $@" DECLARE @startDate DATE DECLARE @endDate DATE @@ -36,7 +36,7 @@ SELECT @currentDate END "; - + } public string GetAxisTableRuntimeName() => "axis"; @@ -66,7 +66,7 @@ public override string GetDatePartOfColumn(AxisIncrement increment, string colum }; /// - /// Gives you the equivalency check for the given axis joined to column1 column. Use this in the JOIN SQL generated by AggregateBuilder + /// Gives you the equivalency check for the given axis joined to column1 column. Use this in the JOIN SQL generated by AggregateBuilder /// /// Step size (day, month, year, quarter) /// The column name or transform from the dataset @@ -127,7 +127,7 @@ ORDER BY axisColumnAlias ).Trim(); } - + protected override string BuildPivotAndAxisAggregate(AggregateCustomLineCollection query) { var syntaxHelper = query.SyntaxHelper; @@ -172,7 +172,7 @@ ORDER BY ", syntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert < QueryComponent.SELECT))), syntaxHelper.Escape(GetDateAxisTableDeclaration(query.Axis)), - + //the entire select query up to the end of the group by (omitting any Top X) syntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert is >= QueryComponent.SELECT and < QueryComponent.OrderBy && @@ -230,7 +230,7 @@ ORDER BY syntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert < QueryComponent.SELECT))), syntaxHelper.Escape(nonPivotColumnAlias), - + //the entire select query up to the end of the group by (ommitting any Top X) syntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert is >= QueryComponent.SELECT and < QueryComponent.OrderBy && @@ -349,6 +349,6 @@ WHILE CHARINDEX('],', @Columns +',', @pos+1)>0 ); return part1; } - + } \ No newline at end of file diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs index 3ae8de4d..f2e255b7 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftQuerySyntaxHelper.cs @@ -18,9 +18,9 @@ private MicrosoftQuerySyntaxHelper() : base(MicrosoftSQLTypeTranslater.Instance, /// /// Maximum database name length. This is less than 128 in order to allow for "_logs" etc getting appended to end. - /// See: https://stackoverflow.com/a/5096245/4824531 + /// See: https://stackoverflow.com/a/5096245/4824531 /// - public override int MaximumDatabaseLength => 100; + public override int MaximumDatabaseLength => 100; public override int MaximumTableLength => 128; public override int MaximumColumnLength => 128; @@ -74,7 +74,7 @@ public override bool IsTimeout(Exception exception) if (sqlE.Number is -2 or 11 or 1205) return true; - //yup, I've seen this behaviour from Sql Server. ExceptionMessage of " " and .Number of + //yup, I've seen this behaviour from Sql Server. ExceptionMessage of " " and .Number of if (string.IsNullOrWhiteSpace(sqlE.Message) && sqlE.Number == 3617) return true; } @@ -96,13 +96,13 @@ public override bool SupportsEmbeddedParameters() { return true; } - + public override string EnsureWrappedImpl(string databaseOrTableName) { return $"[{GetRuntimeNameWithDoubledClosingSquareBrackets(databaseOrTableName)}]"; } - + protected override string UnescapeWrappedNameBody(string name) { return name.Replace("]]","]"); diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs index ed7275c0..bffeb537 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLBulkCopy.cs @@ -113,7 +113,7 @@ private Exception AttemptLineByLineInsert(Exception e, SqlBulkCopy insert, DataT DestinationTableName = insert.DestinationTableName }) { - + foreach (SqlBulkCopyColumnMapping m in insert.ColumnMappings) investigationOneLineAtATime.ColumnMappings.Add(m); @@ -143,7 +143,7 @@ private Exception AttemptLineByLineInsert(Exception e, SqlBulkCopy insert, DataT return new Exception(string.Format(SR.MicrosoftSQLBulkCopy_AttemptLineByLineInsert_BulkInsert_failed_on_data_row__0___1_, line, result), e); } - + 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); @@ -186,17 +186,17 @@ private bool BcpColIdToString(SqlBulkCopy insert, SqlException ex, out string ne 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 length = metadata.GetType().GetField("length", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(metadata); badMapping = insert.ColumnMappings.Cast() .SingleOrDefault(m => string.Equals(m.DestinationColumn , destinationColumn, StringComparison.CurrentCultureIgnoreCase)); - + newMessage = ex.Message.Insert(match.Index + match.Length, $"(Source Column <<{badMapping?.SourceColumn??"unknown"}>> Dest Column <<{destinationColumn}>> which has MaxLength of {length})"); - + return true; } catch (NullReferenceException) diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs index df7c84a5..a907871d 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLDatabaseHelper.cs @@ -14,7 +14,7 @@ public class MicrosoftSQLDatabaseHelper: DiscoveredDatabaseHelper /// /// True to attempt sending "ALTER DATABASE MyDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE" /// before DROP DATABASE command when using . - /// Defaults to true. This command makes dropping databases more robust so is recommended but + /// 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; @@ -136,7 +136,7 @@ public override void DropDatabase(DiscoveredDatabase database) } /// - /// Sends a DROP database command to the . Optionally sets to SINGLE_USER + /// Sends a DROP database command to the . Optionally sets to SINGLE_USER /// first in order to more reliably drop the database. /// /// diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs index e30d9a88..5bc4758d 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLServerHelper.cs @@ -75,7 +75,7 @@ public string GetDatabaseNameFrom(DbConnectionStringBuilder builder) } #endregion - + public override IEnumerable ListDatabases(DbConnectionStringBuilder builder) { //create a copy so as not to corrupt the original @@ -102,7 +102,7 @@ public override string[] ListDatabases(DbConnection con) con.Close(); return databases.ToArray(); } - + public override DbConnectionStringBuilder EnableAsync(DbConnectionStringBuilder builder) { var b = (SqlConnectionStringBuilder) builder; diff --git a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs index fe737054..6ff2bc65 100644 --- a/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs +++ b/FAnsiSql/Implementations/MicrosoftSQL/MicrosoftSQLTableHelper.cs @@ -128,7 +128,7 @@ public override void DropColumn(DbConnection connection, DiscoveredColumn column cmd.ExecuteNonQuery(); } - + public override IEnumerable DiscoverTableValuedFunctionParameters(DbConnection connection,DiscoveredTableValuedFunction discoveredTableValuedFunction, DbTransaction transaction) { var toReturn = new List(); @@ -202,7 +202,7 @@ public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable t { if(transaction != null) cmd.Transaction = transaction.Transaction; - + var p = cmd.CreateParameter(); p.ParameterName = "@table"; p.Value = table.GetRuntimeName(); @@ -214,7 +214,7 @@ public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable t p.Value = table.Schema ?? "dbo"; p.DbType = DbType.String; cmd.Parameters.Add(p); - + p = cmd.CreateParameter(); p.ParameterName = "@database"; p.Value = table.Database.GetRuntimeName(); @@ -224,7 +224,7 @@ public override DiscoveredRelationship[] DiscoverRelationships(DiscoveredTable t using var dt = new DataTable(); var da = table.Database.Server.GetDataAdapter(cmd); da.Fill(dt); - + foreach(DataRow r in dt.Rows) { var fkName = r["FK_NAME"].ToString(); @@ -316,7 +316,7 @@ public override string GetTopXSqlForTable(IHasFullyQualifiedNameToo table, int t { return $"SELECT TOP {topX} * FROM {table.GetFullyQualifiedName()}"; } - + private string GetSQLType_FromSpColumnsResult(DbDataReader r) { var columnType = r["TYPE_NAME"] as string; diff --git a/FAnsiSql/Implementations/MySql/Aggregation/MySqlAggregateHelper.cs b/FAnsiSql/Implementations/MySql/Aggregation/MySqlAggregateHelper.cs index d0a4ff72..00ac8da9 100644 --- a/FAnsiSql/Implementations/MySql/Aggregation/MySqlAggregateHelper.cs +++ b/FAnsiSql/Implementations/MySql/Aggregation/MySqlAggregateHelper.cs @@ -14,7 +14,7 @@ private string GetDateAxisTableDeclaration(IQueryAxis axis) //if the axis is days then there are likely to be thousands of them but if we start adding thousands of years //mysql date falls over with overflow exceptions var thousands = - axis.AxisIncrement == AxisIncrement.Day ? + axis.AxisIncrement == AxisIncrement.Day ? @"JOIN (SELECT 0 thousands UNION ALL SELECT 1000 UNION ALL SELECT 2000 UNION ALL SELECT 3000 @@ -25,7 +25,7 @@ UNION ALL SELECT 7000 UNION ALL SELECT 8000 UNION ALL SELECT 9000 var plusThousands = axis.AxisIncrement == AxisIncrement.Day ? "+ thousands":""; //QueryComponent.JoinInfoJoin - return + return $@" SET @startDate = {axis.StartDate}; @@ -83,9 +83,9 @@ protected override string BuildAxisAggregate(AggregateCustomLineCollection query { var countAlias = query.CountSelect.GetAliasFromText(query.SyntaxHelper); var axisColumnAlias = query.AxisSelect.GetAliasFromText(query.SyntaxHelper) ?? "joinDt"; - + WrapAxisColumnWithDatePartFunction(query,axisColumnAlias); - + return string.Format( @" @@ -110,19 +110,19 @@ ORDER BY GetDatePartOfColumn(query.Axis.AxisIncrement,"dateAxis.dt"), countAlias, - + //the entire query string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert is >= QueryComponent.SELECT and <= QueryComponent.Having)), axisColumnAlias ).Trim(); } - + protected override string BuildPivotAndAxisAggregate(AggregateCustomLineCollection query) { var axisColumnWithoutAlias = query.AxisSelect.GetTextWithoutAlias(query.SyntaxHelper); var part1 = GetPivotPart1(query); - + return string.Format(@" {0} @@ -170,11 +170,11 @@ ORDER BY string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert is >= QueryComponent.FROM and <= QueryComponent.WHERE).Select(x=> query.SyntaxHelper.Escape(x.Text))) ); } - + protected override string BuildPivotOnlyAggregate(AggregateCustomLineCollection query, CustomLine nonPivotColumn) { var part1 = GetPivotPart1(query); - + var joinAlias = nonPivotColumn.GetAliasFromText(query.SyntaxHelper); return string.Format(@" @@ -204,9 +204,9 @@ ORDER BY part1, nonPivotColumn, - //everything inclusive of FROM but stopping before GROUP BY + //everything inclusive of FROM but stopping before GROUP BY query.SyntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert is >= QueryComponent.FROM and < QueryComponent.GroupBy))), - + joinAlias, //any HAVING SQL @@ -231,14 +231,14 @@ private static string GetPivotPart1(AggregateCustomLineCollection query) if (aggregateParameter.Equals("*")) aggregateParameter = "1"; - + //if there is an axis we must ensure we only pull pivot values where the values appear in that axis range var whereDateColumnNotNull = ""; - + if(query.AxisSelect != null) { var axisColumnWithoutAlias = query.AxisSelect.GetTextWithoutAlias(query.SyntaxHelper); - + whereDateColumnNotNull += query.Lines.Any(l => l.LocationToInsert == QueryComponent.WHERE) ? "AND " : "WHERE "; whereDateColumnNotNull += $"{axisColumnWithoutAlias} IS NOT NULL"; } @@ -314,10 +314,10 @@ order by orderBy, havingSqlIfAny ); - + } - + //so janky to double select GROUP_Concat just so we can get dataset* except join.dt -- can we do it once into @columns then again into the other //use mysql; @@ -335,28 +335,28 @@ order by //insert into dateAxis // SELECT distinct (@startDate + INTERVAL c.number Year) AS date -//FROM (SELECT singles + tens + hundreds number FROM +//FROM (SELECT singles + tens + hundreds number FROM //( SELECT 0 singles //UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 //UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 //UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 -//) singles JOIN +//) singles JOIN //(SELECT 0 tens //UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30 //UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60 //UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90 -//) tens JOIN +//) tens JOIN //(SELECT 0 hundreds //UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300 //UNION ALL SELECT 400 UNION ALL SELECT 500 UNION ALL SELECT 600 //UNION ALL SELECT 700 UNION ALL SELECT 800 UNION ALL SELECT 900 -//) hundreds -//ORDER BY number DESC) c +//) hundreds +//ORDER BY number DESC) c //WHERE c.number BETWEEN 0 and 1000; //delete from dateAxis where dt > @endDate; -//SET SESSION group_concat_max_len = 1000000; +//SET SESSION group_concat_max_len = 1000000; //SET @columns = NULL; //SELECT @@ -371,7 +371,7 @@ order by //FROM //( //select `test`.`biochemistry`.`hb_extract` AS Pivot, count(*) AS CountName -//FROM +//FROM //`test`.`biochemistry` //group by `test`.`biochemistry`.`hb_extract` //) as b; @@ -386,7 +386,7 @@ order by //FROM //( //select `test`.`biochemistry`.`hb_extract` AS Pivot, count(*) AS CountName -//FROM +//FROM //`test`.`biochemistry` //group by `test`.`biochemistry`.`hb_extract` //) as b; @@ -399,7 +399,7 @@ order by //CONCAT( //' -//SELECT +//SELECT //YEAR(dateAxis.dt) AS joinDt,',@columnNames,' //FROM //dateAxis @@ -411,13 +411,13 @@ order by //' // ,@columns, //' -//FROM +//FROM //`test`.`biochemistry` //group by //YEAR(`test`.`biochemistry`.`sample_date`) //) dataset //ON dataset.joinDt = YEAR(dateAxis.dt) -//ORDER BY +//ORDER BY //YEAR(dateAxis.dt) //'); diff --git a/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs b/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs index 8e60848e..b38fdac9 100644 --- a/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlDatabaseHelper.cs @@ -86,7 +86,7 @@ public override IEnumerable ListTables(DiscoveredDatabase paren //if we are skipping views if(isView && !includeViews) continue; - + //skip invalid table names if(!querySyntaxHelper.IsValidTableName((string)r[0],out _)) continue; diff --git a/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs b/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs index 2cb04346..8587165b 100644 --- a/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlQuerySyntaxHelper.cs @@ -16,7 +16,7 @@ public class MySqlQuerySyntaxHelper : QuerySyntaxHelper public override int MaximumColumnLength => 64; - + public override string OpenQualifier => "`"; public override string CloseQualifier => "`"; diff --git a/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs b/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs index ed05d825..48dfb491 100644 --- a/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlServerHelper.cs @@ -63,7 +63,7 @@ protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(stri } #endregion - + public override DbConnectionStringBuilder EnableAsync(DbConnectionStringBuilder builder) => builder; //no special stuff required? public override IDiscoveredDatabaseHelper GetDatabaseHelper() => new MySqlDatabaseHelper(); @@ -98,7 +98,7 @@ public override Version GetVersion(DiscoveredServer server) return r["Value"] == DBNull.Value ? null: CreateVersionFromString((string)r["Value"]); return null; } - + public override IEnumerable ListDatabases(DbConnectionStringBuilder builder) { var b = (MySqlConnectionStringBuilder)GetConnectionStringBuilder(builder.ConnectionString); diff --git a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs index 73d81bfd..83053bad 100644 --- a/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs +++ b/FAnsiSql/Implementations/MySql/MySqlTableHelper.cs @@ -58,11 +58,11 @@ public override DiscoveredColumn[] DiscoverColumns(DiscoveredTable discoveredTab if (r["COLUMN_KEY"].Equals("PRI")) toAdd.IsPrimaryKey = true; - + toAdd.IsAutoIncrement = r["Extra"] as string == "auto_increment"; toAdd.Collation = r["COLLATION_NAME"] as string; - //todo the only way to know if something in MySql is unicode is by r["character_set_name"] + //todo the only way to know if something in MySql is unicode is by r["character_set_name"] toAdd.DataType = new DiscoveredDataType(r, TrimIntDisplayValues(r["COLUMN_TYPE"].ToString()), toAdd); diff --git a/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs b/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs index 94df3bd3..9f5037e5 100644 --- a/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs +++ b/FAnsiSql/Implementations/MySql/MySqlTypeTranslater.cs @@ -4,11 +4,11 @@ namespace FAnsi.Implementations.MySql; -public class MySqlTypeTranslater : TypeTranslater +public sealed class MySqlTypeTranslater : TypeTranslater { public static readonly MySqlTypeTranslater Instance = new(); - //yup thats right!, long is string (MEDIUMTEXT) + //yup that's right!, long is string (MEDIUMTEXT) //https://dev.mysql.com/doc/refman/8.0/en/other-vendor-data-types.html private static readonly Regex AlsoBitRegex = new(@"tinyint\(1\)",RegexOptions.IgnoreCase|RegexOptions.Compiled|RegexOptions.CultureInvariant); private static readonly Regex AlsoStringRegex = new("(long)|(enum)|(set)|(text)|(mediumtext)",RegexOptions.IgnoreCase|RegexOptions.Compiled|RegexOptions.CultureInvariant); @@ -24,14 +24,24 @@ private MySqlTypeTranslater() : base(4000, 4000) DateRegex = new Regex(@"(date)|(timestamp)",RegexOptions.IgnoreCase|RegexOptions.Compiled|RegexOptions.CultureInvariant); } + public override int GetLengthIfString(string sqlType) => + sqlType.ToUpperInvariant() switch + { + "TINYTEXT" => 1 << 8, + "TEXT" => 1 << 16, + "MEDIUMTEXT" => 1 << 24, + "LONGTEXT" => int.MaxValue, // Should be 1<<32 but that overflows... + _ => AlsoStringRegex.IsMatch(sqlType) ? int.MaxValue : base.GetLengthIfString(sqlType) + }; + public override string GetStringDataTypeWithUnlimitedWidth() { - return "text"; + return "longtext"; } public override string GetUnicodeStringDataTypeWithUnlimitedWidth() { - return "text"; + return "longtext"; } protected override string GetUnicodeStringDataTypeImpl(int maxExpectedStringWidth) diff --git a/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs b/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs index 1209d573..5c3bfebf 100644 --- a/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs +++ b/FAnsiSql/Implementations/Oracle/Aggregation/OracleAggregateHelper.cs @@ -70,7 +70,7 @@ from dual _ => throw new NotImplementedException() }; } - + protected override string BuildAxisAggregate(AggregateCustomLineCollection query) { //we are trying to produce something like this: diff --git a/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs b/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs index b00a29cf..ccdf20b6 100644 --- a/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs +++ b/FAnsiSql/Implementations/Oracle/OracleBulkCopy.cs @@ -18,7 +18,7 @@ public OracleBulkCopy(DiscoveredTable targetTable, IManagedConnection connection { _server = targetTable.Database.Server; } - + public override int UploadImpl(DataTable dt) { //don't run an insert if there are 0 rows diff --git a/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs b/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs index 4b33df92..a9eee8f3 100644 --- a/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleDatabaseHelper.cs @@ -71,7 +71,7 @@ public override IEnumerable ListTables(DiscoveredDatabase paren using var cmd = new OracleCommand($"SELECT view_name FROM all_views where owner='{database}'", (OracleConnection) connection); cmd.Transaction = transaction as OracleTransaction; var r = cmd.ExecuteReader(); - + while (r.Read()) if(querySyntaxHelper.IsValidTableName((string)r["view_name"],out _)) tables.Add(new DiscoveredTable(parent,r["view_name"].ToString(),querySyntaxHelper,null,TableType.View)); @@ -86,7 +86,7 @@ public override IEnumerable ListTableValuedFuncti { return Array.Empty(); } - + public override DiscoveredStoredprocedure[] ListStoredprocedures(DbConnectionStringBuilder builder, string database) { return Array.Empty(); diff --git a/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs b/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs index ef75e2ac..c05a2b38 100644 --- a/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleQuerySyntaxHelper.cs @@ -14,7 +14,7 @@ public sealed class OracleQuerySyntaxHelper : QuerySyntaxHelper public override int MaximumTableLength => 30; public override int MaximumColumnLength => 30; - + public override string OpenQualifier => "\""; public override string CloseQualifier => "\""; @@ -86,7 +86,7 @@ public override string GetScalarFunctionSql(MandatoryScalarFunctions function) = /// public override string GetAutoIncrementKeywordIfAny() { - //this is handled in + //this is handled in return " GENERATED ALWAYS AS IDENTITY"; } diff --git a/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs b/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs index 9ae09568..f86afa1f 100644 --- a/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleServerHelper.cs @@ -67,7 +67,7 @@ protected override DbConnectionStringBuilder GetConnectionStringBuilderImpl(stri return toReturn; } - + public override DbConnectionStringBuilder ChangeDatabase(DbConnectionStringBuilder builder, string newDatabase) { //does not apply to oracle since user = database but we create users with random passwords diff --git a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs index e90dea77..173e2e45 100644 --- a/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs +++ b/FAnsiSql/Implementations/Oracle/OracleTableHelper.cs @@ -56,7 +56,7 @@ FROM all_tab_cols columns.Add(toAdd); } } - + //get auto increment information using (var cmd = @@ -83,8 +83,8 @@ FROM all_tab_cols } } - - //get primary key information + + //get primary key information using(var cmd = new OracleCommand(@"SELECT cols.table_name, cols.column_name, cols.position, cons.status, cons.owner FROM all_constraints cons, all_cons_columns cols WHERE cols.table_name = :table_name AND cols.owner = :owner @@ -107,7 +107,7 @@ FROM all_tab_cols while (r.Read()) columns.Single(c => c.GetRuntimeName().Equals(r["COLUMN_NAME"])).IsPrimaryKey = true;//mark all primary keys as primary } - + return columns.ToArray(); } @@ -121,7 +121,7 @@ public override void DropColumn(DbConnection connection, DiscoveredColumn column $"ALTER TABLE {columnToDrop.Table.GetFullyQualifiedName()} DROP COLUMN {columnToDrop.GetWrappedName()}", (OracleConnection)connection); cmd.ExecuteNonQuery(); } - + private string GetBasicTypeFromOracleType(DbDataReader r) { int? precision = null; @@ -173,7 +173,7 @@ public override void DropFunction(DbConnection connection, DiscoveredTableValued { throw new NotImplementedException(); } - + public override IEnumerable DiscoverTableValuedFunctionParameters(DbConnection connection, DiscoveredTableValuedFunction discoveredTableValuedFunction, DbTransaction transaction) { diff --git a/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs b/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs index 23969665..68a04ea4 100644 --- a/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs +++ b/FAnsiSql/Implementations/Oracle/OracleTypeTranslater.cs @@ -11,14 +11,14 @@ public sealed class OracleTypeTranslater:TypeTranslater public static readonly OracleTypeTranslater Instance = new(); private static readonly Regex AlsoFloatingPointRegex = new("^(NUMBER)|(DEC)",RegexOptions.CultureInvariant|RegexOptions.IgnoreCase|RegexOptions.Compiled); private static readonly Regex AlsoByteArrayRegex = new("(BFILE)|(BLOB)|(RAW)|(ROWID)", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled); - + public const int ExtraLengthPerNonAsciiCharacter = 3; /// /// Oracle specific string types, these are all max length as returned by /// private static readonly Regex AlsoStringRegex = new("^([N]?CLOB)|(LONG)", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled); - + private OracleTypeTranslater(): base(4000, 4000) { diff --git a/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs b/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs index 996542fc..b3398ec1 100644 --- a/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/Aggregation/PostgreSqlAggregateHelper.cs @@ -43,7 +43,7 @@ LEFT JOIN ON dataset.{7} = {1} ORDER BY {1} -", +", //Anything before the SELECT string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert < QueryComponent.SELECT)), GetDatePartOfColumn(query.Axis.AxisIncrement, "generate_series.date"), diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlBulkCopy.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlBulkCopy.cs index a32abbd1..1ace154e 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlBulkCopy.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlBulkCopy.cs @@ -15,7 +15,7 @@ public PostgreSqlBulkCopy(DiscoveredTable discoveredTable, IManagedConnection co { } - + public override int UploadImpl(DataTable dt) { diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs index 5284cf48..1f7e31a9 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlDatabaseHelper.cs @@ -46,7 +46,7 @@ public override IEnumerable ListTables(DiscoveredDatabase paren { //its a system table var schema = r["schemaname"] as string; - + if(querySyntaxHelper.IsValidTableName((string)r["tablename"], out _)) tables.Add(new DiscoveredTable(parent, (string)r["tablename"], querySyntaxHelper, schema)); } @@ -62,7 +62,7 @@ public override IEnumerable ListTables(DiscoveredDatabase paren { //its a system table var schema = r["schemaname"] as string; - + if(querySyntaxHelper.IsValidTableName((string)r["viewname"], out _)) tables.Add(new DiscoveredTable(parent, (string)r["viewname"], querySyntaxHelper, schema, TableType.View)); } @@ -92,7 +92,7 @@ public override void DropDatabase(DiscoveredDatabase database) con.Open(); // https://dba.stackexchange.com/a/11895 - + using(var cmd = new NpgsqlCommand($"UPDATE pg_database SET datallowconn = 'false' WHERE datname = '{database.GetRuntimeName()}';",con)) cmd.ExecuteNonQuery(); @@ -101,7 +101,7 @@ FROM pg_stat_activity WHERE datname = '{database.GetRuntimeName()}';" ,con)) cmd.ExecuteNonQuery(); - + using(var cmd = new NpgsqlCommand($"DROP DATABASE \"{database.GetRuntimeName()}\"",con)) cmd.ExecuteNonQuery(); } diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs index 2b6dba2e..97ea9fc4 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlSyntaxHelper.cs @@ -17,9 +17,9 @@ private PostgreSqlSyntaxHelper() : base(PostgreSqlTypeTranslater.Instance,Postgr public override int MaximumDatabaseLength => 63; public override int MaximumTableLength => 63; public override int MaximumColumnLength => 63; - + public const string DefaultPostgresSchema = "public"; - + public override string OpenQualifier => "\""; public override string CloseQualifier => "\""; @@ -51,7 +51,7 @@ private string GetRuntimeNameWithDoubledDoubleQuotes(string s) { return GetRuntimeName(s)?.Replace("\"","\"\""); } - + protected override string UnescapeWrappedNameBody(string name) { return name.Replace("\"\"","\""); diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs index 3edf470f..cbe65549 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlTableHelper.cs @@ -37,7 +37,7 @@ FROM information_schema.columns p.ParameterName = "@tableName"; p.Value = discoveredTable.GetRuntimeName(); cmd.Parameters.Add(p); - + var p2 = cmd.CreateParameter(); p2.ParameterName = "@schemaName"; p2.Value = string.IsNullOrWhiteSpace(discoveredTable.Schema) ? PostgreSqlSyntaxHelper.DefaultPostgresSchema : discoveredTable.Schema; @@ -53,7 +53,7 @@ FROM information_schema.columns var columnName = discoveredTable is DiscoveredTableValuedFunction ? $"{discoveredTable.GetRuntimeName()}.{r["column_name"]}" : r["column_name"].ToString(); - + var toAdd = new DiscoveredColumn(discoveredTable, columnName, isNullable) { IsAutoIncrement = Equals(r["is_identity"],"YES"), @@ -198,7 +198,7 @@ join information_schema.key_column_usage y p.ParameterName = "@tableName"; p.Value = table.GetRuntimeName(); cmd.Parameters.Add(p); - + var p2 = cmd.CreateParameter(); p2.ParameterName = "@schema"; p2.Value = string.IsNullOrWhiteSpace(table.Schema)? PostgreSqlSyntaxHelper.DefaultPostgresSchema : table.Schema; diff --git a/FAnsiSql/Implementations/PostgreSql/Update/PostgreSqlUpdateHelper.cs b/FAnsiSql/Implementations/PostgreSql/Update/PostgreSqlUpdateHelper.cs index 761766fb..ccaad5d0 100644 --- a/FAnsiSql/Implementations/PostgreSql/Update/PostgreSqlUpdateHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/Update/PostgreSqlUpdateHelper.cs @@ -34,7 +34,7 @@ protected override string BuildUpdateImpl(DiscoveredTable table1, DiscoveredTabl ", string.Join($", {Environment.NewLine}",lines.Where(l=>l.LocationToInsert == QueryComponent.SET) - .Select(c => + .Select(c => //seems like you cant specify the table alias in the SET section of the query c.Text.Replace("t1.",""))), table1.GetFullyQualifiedName(), diff --git a/FAnsiSql/Naming/IHasRuntimeName.cs b/FAnsiSql/Naming/IHasRuntimeName.cs index 5988a83c..98b2d8fc 100644 --- a/FAnsiSql/Naming/IHasRuntimeName.cs +++ b/FAnsiSql/Naming/IHasRuntimeName.cs @@ -2,9 +2,9 @@ namespace FAnsi.Naming; /// /// Interface for an object which references a database location (e.g. a column or a table or a database etc). The 'RuntimeName' is defined as an unqualified string -/// as it could be used at runtime e.g. in an DbDataReader. So for example a TableInfo called '[MyDb]..[MyTbl]' would have a 'RuntimeName' of 'MyTbl'. +/// as it could be used at runtime e.g. in an DbDataReader. So for example a TableInfo called '[MyDb]..[MyTbl]' would have a 'RuntimeName' of 'MyTbl'. /// -/// This also must take into account aliases so an ExtractionInformation class defined as 'UPPER([MyDb]..[MyTbl].[Name]) as CapsName' would have a 'RuntimeName' +/// This also must take into account aliases so an ExtractionInformation class defined as 'UPPER([MyDb]..[MyTbl].[Name]) as CapsName' would have a 'RuntimeName' /// of 'CapsName'. /// public interface IHasRuntimeName diff --git a/Tests/FAnsiTests/Aggregation/AggregationTests.cs b/Tests/FAnsiTests/Aggregation/AggregationTests.cs index c3f490e1..3cf97d9d 100644 --- a/Tests/FAnsiTests/Aggregation/AggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/AggregationTests.cs @@ -118,7 +118,7 @@ private static bool IsMatch(DataRow r, object[] cells) //they are not a match because they are not the same type and cannot be converted return false; } - + if (!a.Equals(b)) return false; } @@ -177,5 +177,5 @@ protected DiscoveredTable GetTestTable(DatabaseType type, bool easy = false) return dic[type]; } - + } \ No newline at end of file diff --git a/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs b/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs index c5bbe68d..9f43b673 100644 --- a/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs @@ -24,11 +24,11 @@ public void Test_Calendar_Year(DatabaseType type) new("SELECT", QueryComponent.SELECT), new("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, - new(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are new("FROM ", QueryComponent.FROM), new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), new("GROUP BY", QueryComponent.GroupBy), - new(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + new(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are }; var axis = new QueryAxis @@ -83,11 +83,11 @@ public void Test_Calendar_Quarter(DatabaseType type) { new("SELECT", QueryComponent.SELECT), new("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, - new(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are new("FROM ", QueryComponent.FROM), new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), new("GROUP BY", QueryComponent.GroupBy), - new(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + new(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are }; var axis = new QueryAxis @@ -128,11 +128,11 @@ public void Test_Calendar_Month(DatabaseType type) new("SELECT", QueryComponent.SELECT), new("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, - new(syntax.EnsureWrapped("EventDate"), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new(syntax.EnsureWrapped("EventDate"), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are new("FROM ", QueryComponent.FROM), new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), new("GROUP BY", QueryComponent.GroupBy), - new(syntax.EnsureWrapped("EventDate"), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + new(syntax.EnsureWrapped("EventDate"), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are }; var axis = new QueryAxis @@ -172,11 +172,11 @@ public void Test_Calendar_Day(DatabaseType type) new("SELECT", QueryComponent.SELECT), new("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, - new(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are new("FROM ", QueryComponent.FROM), new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), new("GROUP BY", QueryComponent.GroupBy), - new(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + new(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are }; var axis = new QueryAxis @@ -216,11 +216,11 @@ public void Test_Calendar_ToToday(DatabaseType type) new("SELECT", QueryComponent.SELECT), new("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, - new(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are new("FROM ", QueryComponent.FROM), new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), new("GROUP BY", QueryComponent.GroupBy), - new(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + new(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are }; var axis = new QueryAxis @@ -284,12 +284,12 @@ public void Test_Calendar_SELECTColumnOrder_CountAfterAxisColumn(DatabaseType ty { new("SELECT", QueryComponent.SELECT), new($"{eventDate.GetFullyQualifiedName()},", QueryComponent.QueryTimeColumn) - { Role = CustomLineRole.Axis }, //tell it which the axis are + { Role = CustomLineRole.Axis }, //tell it which the axis are new("count(*) as MyCount", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, new("FROM ", QueryComponent.FROM), new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), new("GROUP BY", QueryComponent.GroupBy), - new(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + new(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are }; var axis = new QueryAxis diff --git a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs index 334081a4..b2b3cded 100644 --- a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs @@ -28,14 +28,14 @@ public void Test_Calendar_WithPivot(DatabaseType type,bool easy) new("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, new("EventDate,", QueryComponent.QueryTimeColumn) - { Role = CustomLineRole.Axis }, //tell it which the axis are + { Role = CustomLineRole.Axis }, //tell it which the axis are new("Category", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Pivot }, //tell it which the pivot new("FROM ", QueryComponent.FROM), new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), new("GROUP BY", QueryComponent.GroupBy), new("EventDate,", QueryComponent.GroupBy) - { Role = CustomLineRole.Axis }, //tell it which the axis are + { Role = CustomLineRole.Axis }, //tell it which the axis are new("Category", QueryComponent.GroupBy) { Role = CustomLineRole.Pivot } }; diff --git a/Tests/FAnsiTests/All.cs b/Tests/FAnsiTests/All.cs index 7290ba05..0d9946a1 100644 --- a/Tests/FAnsiTests/All.cs +++ b/Tests/FAnsiTests/All.cs @@ -30,7 +30,7 @@ public class All new object[] {DatabaseType.PostgreSql,false} }; - + /// /// for tests that should run on all DBMS /// with all permutations of true/false for 2 args. Matches exhaustively method signature (DatabaseType,bool,bool) diff --git a/Tests/FAnsiTests/CrossPlatformTests.cs b/Tests/FAnsiTests/CrossPlatformTests.cs index f284faaa..88909067 100644 --- a/Tests/FAnsiTests/CrossPlatformTests.cs +++ b/Tests/FAnsiTests/CrossPlatformTests.cs @@ -17,7 +17,7 @@ namespace FAnsiTests; public class CrossPlatformTests:DatabaseTests { - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void TestTableCreation_NullTableName(DatabaseType type) { @@ -40,7 +40,7 @@ public void DateColumnTests_NoTime(DatabaseType type, object input) var tbl = db.CreateTable("MyTable",new []{new DatabaseColumnRequest("MyDate",new DatabaseTypeRequest(typeof(DateTime)))}); tbl.Insert(new Dictionary { { "MyDate", input } }); - + using (var blk = tbl.BeginBulkInsert()) { using var dt = new DataTable(); @@ -55,7 +55,7 @@ public void DateColumnTests_NoTime(DatabaseType type, object input) Assert.AreEqual(expectedDate, result.Rows[0][0]); Assert.AreEqual(expectedDate, result.Rows[1][0]); } - + [TestCase(DatabaseType.MicrosoftSQLServer, "2/28/1993 5:36:27 AM","en-US")] [TestCase(DatabaseType.MySql, "2/28/1993 5:36:27 AM","en-US")] [TestCase(DatabaseType.Oracle, "2/28/1993 5:36:27 AM","en-US")] @@ -73,7 +73,7 @@ public void DateColumnTests_UkUsFormat_Explicit(DatabaseType type, object input, //basic insert tbl.Insert(new Dictionary { { "MyDate", input } },cultureInfo); - + //then bulk insert, both need to work using (var blk = tbl.BeginBulkInsert(cultureInfo)) { @@ -89,7 +89,7 @@ public void DateColumnTests_UkUsFormat_Explicit(DatabaseType type, object input, Assert.AreEqual(expectedDate, result.Rows[0][0]); Assert.AreEqual(expectedDate, result.Rows[1][0]); } - + /// /// Since DateTimes are converted in DataTable in memory before being up loaded to the database we need to check @@ -313,7 +313,7 @@ public void ForeignKeyCreationTest(DatabaseType type) }); var parentIdPkCol = tblParent.DiscoverColumn("ID"); - + var parentIdFkCol = new DatabaseColumnRequest("Parent_ID", new DatabaseTypeRequest(typeof (int))); var tblChild = database.CreateTable("Child", new[] @@ -344,7 +344,7 @@ public void ForeignKeyCreationTest(DatabaseType type) var cmd = tblParent.Database.Server.GetCommand( $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (100,'chucky')", con); - + //violation of fk Assert.That(() => cmd.ExecuteNonQuery(), Throws.Exception); @@ -353,7 +353,7 @@ public void ForeignKeyCreationTest(DatabaseType type) tblParent.Database.Server.GetCommand( $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (1,'chucky2')", con).ExecuteNonQuery(); } - + Assert.AreEqual(2,tblParent.GetRowCount()); Assert.AreEqual(2, tblChild.GetRowCount()); @@ -364,7 +364,7 @@ public void ForeignKeyCreationTest(DatabaseType type) var cmd = tblParent.Database.Server.GetCommand($"DELETE FROM {tblParent.GetFullyQualifiedName()}", con); cmd.ExecuteNonQuery(); } - + Assert.AreEqual(0,tblParent.GetRowCount()); Assert.AreEqual(0, tblChild.GetRowCount()); } @@ -412,7 +412,7 @@ public void ForeignKeyCreationTest_TwoColumns(DatabaseType type, bool cascadeDel dt.Columns.Add("Name"); dt.Rows.Add(1,2, "Bob"); - + intoParent.Upload(dt); } @@ -481,10 +481,10 @@ public void CreateMaxVarcharColumns(DatabaseType type) public void CreateMaxVarcharColumnFromDataTable(DatabaseType type) { var database = GetTestDatabase(type); - + var dt = new DataTable(); dt.Columns.Add("MassiveColumn"); - + var sb = new StringBuilder("Amaa"); for (var i = 0; i < 10000; i++) sb.Append(i); @@ -552,7 +552,7 @@ public void AddColumnTest(DatabaseType type,bool useTransaction) { tbl.AddColumn(newColumnName, new DatabaseTypeRequest(typeof(DateTime)), true, 1000); } - + //new column should exist var newCol = tbl.DiscoverColumn(newColumnName); @@ -566,7 +566,7 @@ public void AddColumnTest(DatabaseType type,bool useTransaction) //sql server can't handle altering primary key columns or anything with a foreign key on it too! if (type == DatabaseType.MicrosoftSQLServer) - fieldsToAlter.Remove("Field1"); + fieldsToAlter.Remove("Field1"); foreach (var fieldName in fieldsToAlter) { @@ -679,7 +679,7 @@ public void TestIntDataTypes(DatabaseType type) Assert.AreEqual(2, size.NumbersAfterDecimalPlace); Assert.AreEqual(5, size.Precision); Assert.AreEqual(2, size.Scale); - + dt = tbl.GetDataTable(); Assert.AreEqual(1, dt.Rows.OfType().Count(r => Convert.ToDecimal(r[0]) == new decimal(100.0f))); Assert.AreEqual(1, dt.Rows.OfType().Count(r => Convert.ToDecimal(r[0]) == new decimal(105.0f))); @@ -704,7 +704,7 @@ public void TestFloatDataTypes(DatabaseType type) Assert.AreEqual(1,dt.Rows.OfType().Count(r=>Convert.ToDecimal(r[0]) == new decimal(100.0f))); Assert.AreEqual(1, dt.Rows.OfType().Count(r => Convert.ToDecimal(r[0]) == new decimal(105.0f))); Assert.AreEqual(1, dt.Rows.OfType().Count(r => Convert.ToDecimal(r[0]) == new decimal(2.1f))); - + var col = tbl.DiscoverColumn("MyCol"); var size = col.DataType.GetDecimalSize(); @@ -713,7 +713,7 @@ public void TestFloatDataTypes(DatabaseType type) Assert.AreEqual(1,size.NumbersAfterDecimalPlace); Assert.AreEqual(4, size.Precision); Assert.AreEqual(1, size.Scale); - + col.DataType.AlterTypeTo("decimal(5,2)"); size = tbl.DiscoverColumn("MyCol").DataType.GetDecimalSize(); @@ -737,7 +737,7 @@ public void HorribleDatabaseAndTableNames(DatabaseType type,string horribleDatab database = database.Server.ExpectDatabase(horribleDatabaseName); database.Create(true); - + SqlConnection.ClearAllPools(); try @@ -798,7 +798,7 @@ public void HorribleDatabaseAndTableNames(DatabaseType type,string horribleDatab [TestCase(DatabaseType.PostgreSql, "my.database", "my.table", "my.col")] public void UnsupportedEntityNames(DatabaseType type, string horribleDatabaseName, string horribleTableName,string columnName) { - + var database = GetTestDatabase(type); //ExpectDatabase with illegal name @@ -812,7 +812,7 @@ public void UnsupportedEntityNames(DatabaseType type, string horribleDatabaseNam "Table .* contained unsupported .* characters", Assert.Throws(()=>database.ExpectTable(horribleTableName)) ?.Message); - + //CreateTable with illegal name StringAssert.IsMatch( "Table .* contained unsupported .* characters", @@ -832,7 +832,7 @@ public void UnsupportedEntityNames(DatabaseType type, string horribleDatabaseNam ?.Message); AssertCanCreateDatabases(); - + //CreateDatabase with illegal name StringAssert.IsMatch( "Database .* contained unsupported .* characters", @@ -868,7 +868,7 @@ public void HorribleColumnNames(DatabaseType type, string horribleDatabaseName, dt.PrimaryKey = new[] {dt.Columns[0]}; var tbl = database.CreateTable(horribleTableName, dt); - + Assert.AreEqual(1, tbl.GetRowCount()); Assert.IsTrue(tbl.DiscoverColumns().Single().IsPrimaryKey); @@ -876,7 +876,7 @@ public void HorribleColumnNames(DatabaseType type, string horribleDatabaseName, Assert.AreEqual(1,tbl.GetDataTable().Rows.Count); tbl.Insert(new Dictionary { {columnName,"fff" } }); - + Assert.AreEqual(2,tbl.GetDataTable().Rows.Count); } finally @@ -929,7 +929,7 @@ public void CreateTable_DefaultTest_Date(DatabaseType type) var tbl = database.CreateTable("MyTable", new[] { - new DatabaseColumnRequest("Name", new DatabaseTypeRequest(typeof(string),100)), + new DatabaseColumnRequest("Name", new DatabaseTypeRequest(typeof(string),100)), new DatabaseColumnRequest("myDt", new DatabaseTypeRequest(typeof (DateTime))) { AllowNulls = false, @@ -937,7 +937,7 @@ public void CreateTable_DefaultTest_Date(DatabaseType type) } }); DateTime currentValue; - + using (var insert = tbl.BeginBulkInsert()) { using var dt = new DataTable(); @@ -951,7 +951,7 @@ public void CreateTable_DefaultTest_Date(DatabaseType type) var dt2 = tbl.GetDataTable(); var databaseValue = (DateTime)dt2.Rows.Cast().Single()["myDt"]; - + Assert.AreEqual(currentValue.Year,databaseValue.Year); Assert.AreEqual(currentValue.Month, databaseValue.Month); Assert.AreEqual(currentValue.Day, databaseValue.Day); @@ -982,7 +982,7 @@ public void CreateTable_DefaultTest_Guid(DatabaseType type) var tbl = database.CreateTable("MyTable", new[] { - new DatabaseColumnRequest("Name", new DatabaseTypeRequest(typeof(string),100)), + new DatabaseColumnRequest("Name", new DatabaseTypeRequest(typeof(string),100)), new DatabaseColumnRequest("MyGuid", new DatabaseTypeRequest(typeof (string))) { AllowNulls = false, @@ -1002,7 +1002,7 @@ public void CreateTable_DefaultTest_Guid(DatabaseType type) var dt2 = tbl.GetDataTable(); var databaseValue = (string)dt2.Rows.Cast().Single()["MyGuid"]; - + Assert.IsNotNull(databaseValue); TestContext.WriteLine(databaseValue); } @@ -1014,9 +1014,9 @@ public void Test_BulkInserting_LotsOfDates(DatabaseType type) var db = GetTestDatabase(type); var tbl = db.CreateTable("LotsOfDatesTest",new DatabaseColumnRequest[] - { + { new("ID",new DatabaseTypeRequest(typeof(int))), - new("MyDate",new DatabaseTypeRequest(typeof(DateTime))), + new("MyDate",new DatabaseTypeRequest(typeof(DateTime))), new("MyString",new DatabaseTypeRequest(typeof(string),int.MaxValue)) }); @@ -1024,9 +1024,9 @@ public void Test_BulkInserting_LotsOfDates(DatabaseType type) foreach(var s in someDates) { tbl.Insert(new Dictionary - { - {"ID",1}, - {"MyDate",s}, + { + {"ID",1}, + {"MyDate",s}, {"MyString",Guid.NewGuid().ToString()} },culture ); diff --git a/Tests/FAnsiTests/DatabaseTests.cs b/Tests/FAnsiTests/DatabaseTests.cs index 37a3b28f..9a64b81d 100644 --- a/Tests/FAnsiTests/DatabaseTests.cs +++ b/Tests/FAnsiTests/DatabaseTests.cs @@ -38,7 +38,7 @@ public void CheckFiles() ImplementationManager.Load(); var file = Path.Combine(TestContext.CurrentContext.TestDirectory, TestFilename); - + Assert.IsTrue(File.Exists(file),"Could not find " + TestFilename); var doc = XDocument.Load(file); @@ -57,7 +57,7 @@ public void CheckFiles() throw new Exception($"Missing element 'TestScratchDatabase' in {TestFilename}"); _testScratchDatabase = e.Value; - + foreach (var element in root.Elements("TestDatabase")) { var type = element.Element("DatabaseType")?.Value; @@ -65,9 +65,9 @@ public void CheckFiles() if(!Enum.TryParse(type, out DatabaseType databaseType)) throw new Exception($"Could not parse DatabaseType {type}"); - + var constr = element.Element("ConnectionString")?.Value; - + TestConnectionStrings.Add(databaseType,constr); } } diff --git a/Tests/FAnsiTests/Examples.cs b/Tests/FAnsiTests/Examples.cs index 5b48089c..0cccf849 100644 --- a/Tests/FAnsiTests/Examples.cs +++ b/Tests/FAnsiTests/Examples.cs @@ -9,9 +9,9 @@ namespace FAnsiTests; internal class TestExamples : DatabaseTests -{ +{ [Ignore("Test only works when the hard coded connection strings pass, this test is used to build clear examples in the documentation")] - [Test] + [Test] public void Simple_Example() { //Some data we want to load diff --git a/Tests/FAnsiTests/ManagedConnectionTests.cs b/Tests/FAnsiTests/ManagedConnectionTests.cs index d46ed61b..cfb5bbc8 100644 --- a/Tests/FAnsiTests/ManagedConnectionTests.cs +++ b/Tests/FAnsiTests/ManagedConnectionTests.cs @@ -80,7 +80,7 @@ public void Test_GetManagedConnection_OngoingTransaction(DatabaseType dbType) using (ongoingCon = db.Server.BeginNewTransactedConnection()) { var ongoingTrans = ongoingCon.ManagedTransaction; - + //BeginNewTransactedConnection should open itself Assert.AreEqual(ConnectionState.Open,ongoingCon.Connection.State); Assert.IsNotNull(ongoingTrans); @@ -105,7 +105,7 @@ public void Test_GetManagedConnection_OngoingTransaction(DatabaseType dbType) /// /// Same as Test_GetManagedConnection_OngoingTransaction except we call or - /// instead of relying on the outermost using finally + /// instead of relying on the outermost using finally /// /// /// Whether to commit @@ -119,7 +119,7 @@ public void Test_GetManagedConnection_OngoingTransaction_WithCommitRollback(Data using (ongoingCon = db.Server.BeginNewTransactedConnection()) { var ongoingTrans = ongoingCon.ManagedTransaction; - + //BeginNewTransactedConnection should open itself Assert.AreEqual(ConnectionState.Open,ongoingCon.Connection.State); Assert.IsNotNull(ongoingTrans); diff --git a/Tests/FAnsiTests/PackageListIsCorrectTests.cs b/Tests/FAnsiTests/PackageListIsCorrectTests.cs index 144fd64b..dafe6508 100644 --- a/Tests/FAnsiTests/PackageListIsCorrectTests.cs +++ b/Tests/FAnsiTests/PackageListIsCorrectTests.cs @@ -9,7 +9,7 @@ namespace DicomTypeTranslation.Tests; /// -/// Tests to confirm that the dependencies in csproj files (NuGet packages) match those in the .nuspec files and that packages.md +/// Tests to confirm that the dependencies in csproj files (NuGet packages) match those in the .nuspec files and that packages.md /// lists the correct versions (in documentation) /// public class PackageListIsCorrectTests diff --git a/Tests/FAnsiTests/Properties/AssemblyInfo.cs b/Tests/FAnsiTests/Properties/AssemblyInfo.cs index d29dcfbc..10074433 100644 --- a/Tests/FAnsiTests/Properties/AssemblyInfo.cs +++ b/Tests/FAnsiTests/Properties/AssemblyInfo.cs @@ -1,7 +1,7 @@ using System.Runtime.InteropServices; -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] diff --git a/Tests/FAnsiTests/Query/QuerySyntaxHelperDatabaseTests.cs b/Tests/FAnsiTests/Query/QuerySyntaxHelperDatabaseTests.cs index af1b5267..7e1cb73a 100644 --- a/Tests/FAnsiTests/Query/QuerySyntaxHelperDatabaseTests.cs +++ b/Tests/FAnsiTests/Query/QuerySyntaxHelperDatabaseTests.cs @@ -7,7 +7,7 @@ namespace FAnsiTests.Query; internal class QuerySyntaxHelperDatabaseTests : DatabaseTests { - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void Test_HowDoWeAchieveMd5(DatabaseType dbType) { diff --git a/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs b/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs index e265b69b..d026cddf 100644 --- a/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs +++ b/Tests/FAnsiTests/Query/QuerySyntaxHelperTests.cs @@ -10,18 +10,18 @@ namespace FAnsiTests.Query; internal class QuerySyntaxHelperTests { - + //Oracle always uppers everything because... Oracle [TestCase(DatabaseType.Oracle,"CHI","\"TEST_ScratchArea\".public.\"Biochemistry\".\"chi\"")] [TestCase(DatabaseType.PostgreSql,"chi","\"TEST_ScratchArea\".public.\"Biochemistry\".\"chi\"")] - + [TestCase(DatabaseType.Oracle,"FRANK","count(*) as Frank")] [TestCase(DatabaseType.PostgreSql,"Frank","count(*) as Frank")] [TestCase(DatabaseType.Oracle,"FRANK","count(cast(1 as int)) as Frank")] [TestCase(DatabaseType.PostgreSql,"Frank","count(cast(1 as int)) as Frank")] - + [TestCase(DatabaseType.Oracle,"FRANK","count(cast(1 as int)) as \"Frank\"")] [TestCase(DatabaseType.PostgreSql,"Frank","count(cast(1 as int)) as \"Frank\"")] [TestCase(DatabaseType.MySql,"Frank","count(cast(1 as int)) as `Frank`")] @@ -36,11 +36,11 @@ internal class QuerySyntaxHelperTests [TestCase(DatabaseType.MicrosoftSQLServer,"zombie","dbo.GetMyCoolThing(\"Magic Fun Times\") as zombie")] [TestCase(DatabaseType.MySql,"zombie","dbo.GetMyCoolThing(\"Magic Fun Times\") as zombie")] [TestCase(DatabaseType.PostgreSql,"zombie","dbo.GetMyCoolThing(\"Magic Fun Times\") as zombie")] - + [TestCase(DatabaseType.Oracle,"MYCOL","\"mydb\".\"mytbl\".\"mycol\"")] [TestCase(DatabaseType.MicrosoftSQLServer,"mycol","[mydb].[mytbl].[mycol]")] [TestCase(DatabaseType.MySql,"mycol","`mydb`.`mytbl`.`mycol`")] - [TestCase(DatabaseType.PostgreSql,"mycol","\"mydb\".\"mytbl\".\"mycol\"")] + [TestCase(DatabaseType.PostgreSql,"mycol","\"mydb\".\"mytbl\".\"mycol\"")] public void SyntaxHelperTest_GetRuntimeName(DatabaseType dbType, string expected, string forInput) { var syntaxHelper = ImplementationManager.GetImplementation(dbType).GetQuerySyntaxHelper(); @@ -86,7 +86,7 @@ public void SyntaxHelperTest_GetRuntimeName_MultipleCalls(DatabaseType dbType, } } } - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void EnsureWrapped_MultipleCalls(DatabaseType dbType) { diff --git a/Tests/FAnsiTests/Server/ServerTests.cs b/Tests/FAnsiTests/Server/ServerTests.cs index af4c0572..016e35ba 100644 --- a/Tests/FAnsiTests/Server/ServerTests.cs +++ b/Tests/FAnsiTests/Server/ServerTests.cs @@ -69,7 +69,7 @@ public void ServerHelper_GetConnectionStringBuilder(DatabaseType type) Assert.AreEqual("wacky",server.ExplicitPasswordIfAny); } - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypesWithBoolFlags))] public void ServerHelper_GetConnectionStringBuilder_NoDatabase(DatabaseType type,bool useWhitespace) { @@ -224,5 +224,5 @@ public void TestServer_GetVersion(DatabaseType dbType) Assert.Greater(ver.Major,0); } - + } \ No newline at end of file diff --git a/Tests/FAnsiTests/Table/BadNamesTests.cs b/Tests/FAnsiTests/Table/BadNamesTests.cs index bcd5e447..f3f65e68 100644 --- a/Tests/FAnsiTests/Table/BadNamesTests.cs +++ b/Tests/FAnsiTests/Table/BadNamesTests.cs @@ -38,8 +38,8 @@ private DiscoveredTable SetupBadNamesTable(DatabaseType dbType) var (badTableName,badColumnName,badColumnName2) = GetBadNames(dbType); return db.CreateTable(badTableName,new[] { - new DatabaseColumnRequest(badColumnName,new DatabaseTypeRequest(typeof(string),100)), - new DatabaseColumnRequest(badColumnName2,new DatabaseTypeRequest(typeof(int))) + new DatabaseColumnRequest(badColumnName,new DatabaseTypeRequest(typeof(string),100)), + new DatabaseColumnRequest(badColumnName2,new DatabaseTypeRequest(typeof(int))) }); } @@ -125,14 +125,14 @@ public void BadNames_TopXColumn(DatabaseType dbType,bool noNulls) Assert.IsTrue(r.Read()); Assert.AreEqual(!noNulls,r.Read()); - + Assert.IsFalse(r.Read()); } tbl.Drop(); } - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void BadNames_DropColumn(DatabaseType dbType) { @@ -181,7 +181,7 @@ public void BadNames_TopXTable(DatabaseType dbType) tbl.Drop(); } - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void BadNames_DiscoverRelationships(DatabaseType dbType) { @@ -191,8 +191,8 @@ public void BadNames_DiscoverRelationships(DatabaseType dbType) var tbl1 = db.CreateTable(badTableName,new[] { - new DatabaseColumnRequest(badColumnName,new DatabaseTypeRequest(typeof(string),100)){IsPrimaryKey = true }, - new DatabaseColumnRequest("Frrrrr ##' ank",new DatabaseTypeRequest(typeof(int))) + new DatabaseColumnRequest(badColumnName,new DatabaseTypeRequest(typeof(string),100)){IsPrimaryKey = true }, + new DatabaseColumnRequest("Frrrrr ##' ank",new DatabaseTypeRequest(typeof(int))) }); var pk = tbl1.DiscoverColumns().Single(c=>c.IsPrimaryKey); @@ -200,7 +200,7 @@ public void BadNames_DiscoverRelationships(DatabaseType dbType) var tbl2 = db.CreateTable(new CreateTableArgs(db, $"{badTableName}2",null) { - ExplicitColumnDefinitions = new []{fk = new DatabaseColumnRequest($"{badColumnName}2",new DatabaseTypeRequest(typeof(string),100)) }, + ExplicitColumnDefinitions = new []{fk = new DatabaseColumnRequest($"{badColumnName}2",new DatabaseTypeRequest(typeof(string),100)) }, ForeignKeyPairs = new Dictionary {{fk, pk} } }); @@ -237,7 +237,7 @@ public void BadNames_BulkInsert(DatabaseType dbType) tbl.Drop(); } - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void BadNames_Rename(DatabaseType dbType) { diff --git a/Tests/FAnsiTests/Table/BasicInsertTests.cs b/Tests/FAnsiTests/Table/BasicInsertTests.cs index c3851cd6..fb735a85 100644 --- a/Tests/FAnsiTests/Table/BasicInsertTests.cs +++ b/Tests/FAnsiTests/Table/BasicInsertTests.cs @@ -12,7 +12,7 @@ internal class BasicInsertTests:DatabaseTests [TestCase(DatabaseType.MySql,"Dave")] [TestCase(DatabaseType.Oracle, "Dave")] [TestCase(DatabaseType.PostgreSql, "Dave")] - + [TestCase(DatabaseType.MicrosoftSQLServer, @"].;\""ffff [")] @@ -82,7 +82,7 @@ public void CreateTableAndInsertAValue_ReturnsIdentity(DatabaseType type) var tbl = db.CreateTable("InsertTable", new[] { - new DatabaseColumnRequest("myidentity",new DatabaseTypeRequest(typeof(int))){IsPrimaryKey = true,IsAutoIncrement = true}, + new DatabaseColumnRequest("myidentity",new DatabaseTypeRequest(typeof(int))){IsPrimaryKey = true,IsAutoIncrement = true}, new DatabaseColumnRequest("Name",new DatabaseTypeRequest(typeof(string),100)) }); diff --git a/Tests/FAnsiTests/Table/BulkInsertTest.cs b/Tests/FAnsiTests/Table/BulkInsertTest.cs index 0c383cb8..1873c0ee 100644 --- a/Tests/FAnsiTests/Table/BulkInsertTest.cs +++ b/Tests/FAnsiTests/Table/BulkInsertTest.cs @@ -476,7 +476,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas cts.Cancel(); //creation should have been cancelled at the database level var ex = Assert.Throws(()=>tbl.CreatePrimaryKey(con.ManagedTransaction,cts.Token,50000,bobCol)); - + //MySql seems to be throwing null reference inside ExecuteNonQueryAsync. No idea why but it is still cancelled if(type != DatabaseType.MySql) StringAssert.Contains("cancel",ex?.InnerException?.Message); @@ -653,7 +653,7 @@ public void TestBulkInsert_Unicode(DatabaseType dbType) Assert.Contains("你好",dtResult.Rows.Cast().Select(r=>r[0]).ToArray()); Assert.Contains("مرحبا",dtResult.Rows.Cast().Select(r=>r[0]).ToArray()); table.Drop(); - } + } [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void TestBulkInsert_SchemaTooNarrow_StringError(DatabaseType type) @@ -762,7 +762,7 @@ public void TestBulkInsert_SchemaTooNarrow_DecimalError(DatabaseType type) dt.Rows.Add(60,"Jamie",1.2); dt.Rows.Add(30,"Frank",1.3); - dt.Rows.Add(11,"Toad",111111111.11); //bad data + dt.Rows.Add(11,"Toad",111111111.11); //bad data dt.Rows.Add(100,"King"); dt.Rows.Add(10,"Frog"); @@ -770,7 +770,7 @@ public void TestBulkInsert_SchemaTooNarrow_DecimalError(DatabaseType type) bulk.Timeout = 30; Exception ex = null; - try + try { bulk.Upload(dt); } @@ -827,7 +827,7 @@ public void TestBulkInsert_BadDecimalFormat_DecimalError(DatabaseType type) dt.Rows.Add(60,"Jamie",1.2); dt.Rows.Add(30,"Frank",1.3); - dt.Rows.Add(11,"Toad","."); //bad data + dt.Rows.Add(11,"Toad","."); //bad data dt.Rows.Add(100,"King"); dt.Rows.Add(10,"Frog"); @@ -835,7 +835,7 @@ public void TestBulkInsert_BadDecimalFormat_DecimalError(DatabaseType type) bulk.Timeout = 30; Exception ex = null; - try + try { bulk.Upload(dt); } diff --git a/Tests/FAnsiTests/Table/CreateTableTests.cs b/Tests/FAnsiTests/Table/CreateTableTests.cs index 2585943f..b1280fd0 100644 --- a/Tests/FAnsiTests/Table/CreateTableTests.cs +++ b/Tests/FAnsiTests/Table/CreateTableTests.cs @@ -49,7 +49,7 @@ public void TestTableCreation(DatabaseType type) new DatabaseColumnRequest("address", new DatabaseTypeRequest(typeof (string), 500)), new DatabaseColumnRequest("dob", new DatabaseTypeRequest(typeof (DateTime)),false), new DatabaseColumnRequest("score", - new DatabaseTypeRequest(typeof (decimal), null, new DecimalSize(5, 3))) //<- e.g. 12345.123 + new DatabaseTypeRequest(typeof (decimal), null, new DecimalSize(5, 3))) //<- e.g. 12345.123 }); @@ -160,7 +160,7 @@ public void CreateTable_PrimaryKey_FromDataTable(DatabaseType databaseType) Assert.IsTrue(table.DiscoverColumn("Name").IsPrimaryKey); } - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void CreateTable_PrimaryKey_FromColumnRequest(DatabaseType databaseType) { @@ -285,7 +285,7 @@ public void Test_OracleBit_IsNotStringAnyMore() } - + [TestCase(DatabaseType.MicrosoftSQLServer, "didn’t")] //<- it's a ’ not a ' [TestCase(DatabaseType.MicrosoftSQLServer, "Æther")] [TestCase(DatabaseType.MicrosoftSQLServer, "乗")] @@ -406,7 +406,7 @@ public void Test_CreateTable_DoNotRetype(DatabaseType dbType) tbl.Drop(); } - + /// /// Just to check that clone on properly clones /// @@ -460,7 +460,7 @@ public void CreateTable_ObjectColumns_StringContent(DatabaseType dbType) StringAssert.Contains("System.Object",ex?.Message); } - + /// /// Tests how we can customize how "T" and "F" etc are interpreted (either as boolean true/false or as string). This test /// uses the static defaults in . diff --git a/Tests/FAnsiTests/Table/ForeignKeyTests.cs b/Tests/FAnsiTests/Table/ForeignKeyTests.cs index ed02619d..c25158ad 100644 --- a/Tests/FAnsiTests/Table/ForeignKeyTests.cs +++ b/Tests/FAnsiTests/Table/ForeignKeyTests.cs @@ -36,7 +36,7 @@ public void TestForeignKey_OneColumnKey(DatabaseType dbType, bool cascade) }, new Dictionary { {requested_fkCol,discovered_pkCol} - + }, cascade); var discovered_fkCol = childTable.DiscoverColumn("Parent_Id"); @@ -189,7 +189,7 @@ public void Test_ThreeTables_OnePrimary(DatabaseType dbType, bool useTransaction Assert.Contains(t2, sort2.Order.ToList()); Assert.Contains(t3, sort2.Order.ToList()); } - + [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] public void Test_ThreeTables_TwoPrimary(DatabaseType dbType) { diff --git a/Tests/FAnsiTests/Table/TopXTests.cs b/Tests/FAnsiTests/Table/TopXTests.cs index c0dd7bb8..bf1a6152 100644 --- a/Tests/FAnsiTests/Table/TopXTests.cs +++ b/Tests/FAnsiTests/Table/TopXTests.cs @@ -58,7 +58,7 @@ public void Test_TopX_OrderBy(DatabaseType type,bool asc) var sqlcol = tbl.DiscoverColumn("X").GetTopXSql(1,false); Assert.AreEqual(DBNull.Value,db.Server.GetCommand(sqlcol,con).ExecuteScalar()); - + sqlcol = tbl.DiscoverColumn("X").GetTopXSql(1,true); Assert.AreEqual("fish",db.Server.GetCommand(sqlcol,con).ExecuteScalar()); diff --git a/Tests/FAnsiTests/Table/UpdateTests.cs b/Tests/FAnsiTests/Table/UpdateTests.cs index eeb0c82d..124c54bb 100644 --- a/Tests/FAnsiTests/Table/UpdateTests.cs +++ b/Tests/FAnsiTests/Table/UpdateTests.cs @@ -36,7 +36,7 @@ public void Test_UpdateTableFromJoin(DatabaseType dbType) dt2.Columns.Add("Score"); dt2.Rows.Add("Dave", 50); dt2.Rows.Add("Frank", 900); - + tbl2 = db.CreateTable("NewScoresTable", dt2); } diff --git a/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs b/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs index 48c4eb71..c0f2c767 100644 --- a/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs +++ b/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs @@ -12,7 +12,7 @@ namespace FAnsiTests.TypeTranslation; /// /// Critically it covers fallback from one data type estimate to another based on new data e.g. if you see a "100" then a "1" then a "1.1" /// the final estimate should be decimal(4,1) to allow for both 100.0f and 1.1f. -/// +/// /// public class GuesserTests { @@ -413,7 +413,7 @@ public void TestGuesser_NumberOfDecimalPlaces() Assert.AreEqual(9, t.Guess.Size.NumbersBeforeDecimalPlace); Assert.AreEqual(14, t.Guess.Size.NumbersAfterDecimalPlace); } - + [Test] public void TestGuesser_TrailingZeroesFallbackToString() @@ -616,7 +616,7 @@ public void TestGuesser_RandomCrud(string randomCrud) t.AdjustToCompensateForValue(randomCrud); Assert.AreEqual(typeof(string), t.Guess.CSharpType); } - + [Test] public void TestGuesser_ScientificNotation() { diff --git a/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs b/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs index 334ad01c..4225f1e1 100644 --- a/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs +++ b/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs @@ -23,7 +23,7 @@ namespace FAnsiTests.TypeTranslation; public class TypeTranslaterTests : DatabaseTests { private readonly Dictionary _translaters = new(); - + [OneTimeSetUp] public void SetupDatabases() { @@ -52,13 +52,13 @@ public void Test_CSharpToDbType_String10(DatabaseType type,string expectedType) Assert.AreEqual(expectedType,_translaters[type].GetSQLDBTypeForCSharpType(cSharpType));} [TestCase(DatabaseType.MicrosoftSQLServer, "varchar(max)")] - [TestCase(DatabaseType.MySql, "text")] + [TestCase(DatabaseType.MySql, "longtext")] [TestCase(DatabaseType.Oracle, "CLOB")] [TestCase(DatabaseType.PostgreSql, "text")] public void Test_CSharpToDbType_StringMax(DatabaseType type,string expectedType) { var cSharpType = new DatabaseTypeRequest(typeof(string), 10000000); - + //Does a request for a max length string give the expected data type? Assert.AreEqual(expectedType,_translaters[type].GetSQLDBTypeForCSharpType(cSharpType)); @@ -73,7 +73,7 @@ public void Test_CSharpToDbType_StringMax(DatabaseType type,string expectedType) [TestCase(DatabaseType.MicrosoftSQLServer, "nvarchar(max)",true)] [TestCase(DatabaseType.MicrosoftSQLServer, "text",false)] [TestCase(DatabaseType.MicrosoftSQLServer, "ntext",true)] - [TestCase(DatabaseType.MySql, "text",false)] + [TestCase(DatabaseType.MySql, "longtext",false)] [TestCase(DatabaseType.Oracle, "CLOB", false)] [TestCase(DatabaseType.PostgreSql, "text", false)] public void Test_GetLengthIfString_VarcharMaxCols(DatabaseType type, string datatype, bool expectUnicode) @@ -85,7 +85,7 @@ public void Test_GetLengthIfString_VarcharMaxCols(DatabaseType type, string data Assert.AreEqual(int.MaxValue, dbType.Width); Assert.AreEqual(expectUnicode, dbType.Unicode); } - + [TestCase(DatabaseType.MicrosoftSQLServer,"bigint",typeof(long))] [TestCase(DatabaseType.MicrosoftSQLServer,"binary",typeof(byte[]))] [TestCase(DatabaseType.MicrosoftSQLServer,"bit",typeof(bool))] @@ -172,7 +172,7 @@ public void Test_GetLengthIfString_VarcharMaxCols(DatabaseType type, string data [TestCase(DatabaseType.MySql, "nchar",typeof(string))] [TestCase(DatabaseType.MySql, "nvarchar(10)",typeof(string))] [TestCase(DatabaseType.MySql, "real",typeof(decimal))] - + [TestCase(DatabaseType.Oracle, "varchar2(10)",typeof(string))] [TestCase(DatabaseType.Oracle, "CHAR(10)", typeof(string))] [TestCase(DatabaseType.Oracle, "CHAR", typeof(string))] @@ -202,25 +202,25 @@ public void Test_GetLengthIfString_VarcharMaxCols(DatabaseType type, string data [TestCase(DatabaseType.Oracle, "DEC(3,2)", typeof(decimal))] [TestCase(DatabaseType.Oracle, "DEC(*,3)", typeof(decimal))] - + //These types are all converted to Number(38) by Oracle : https://docs.oracle.com/cd/A58617_01/server.804/a58241/ch5.htm (See ANSI/ISO, DB2, and SQL/DS Datatypes ) - [TestCase(DatabaseType.Oracle, "INTEGER", typeof(int))] + [TestCase(DatabaseType.Oracle, "INTEGER", typeof(int))] [TestCase(DatabaseType.Oracle, "INT", typeof(int))] [TestCase(DatabaseType.Oracle, "SMALLINT", typeof(int))] //yup, see the link above public void TestIsKnownType(DatabaseType databaseType,string sqlType, Type expectedType) { RunKnownTypeTest(databaseType, sqlType, expectedType); } - + private void RunKnownTypeTest(DatabaseType type, string sqlType, Type expectedType) { //Get test database var db = GetTestDatabase(type); var tt = db.Server.GetQuerySyntaxHelper().TypeTranslater; - + //Create it in database (crashes here if it's an invalid datatype according to DBMS) var tbl = db.CreateTable("TTT", new[] { new DatabaseColumnRequest("MyCol", sqlType) }); - + try { //Find the column on the created table and fetch it @@ -235,7 +235,7 @@ private void RunKnownTypeTest(DatabaseType type, string sqlType, Type expectedTy var Guesser = col.GetGuesser(); Assert.IsNotNull(Guesser.Guess.CSharpType); var tAfter = Guesser.Guess.CSharpType; - + //was the Type REQUESTED correct according to the test case expectation Assert.AreEqual(expectedType, tBefore,"We asked to create a '{0}', DBMS created a '{1}'. FAnsi decided that '{0}' is '{2}' and that '{1}' is '{3}'",sqlType,col.DataType.SQLType,tBefore,tAfter); @@ -250,7 +250,7 @@ private void RunKnownTypeTest(DatabaseType type, string sqlType, Type expectedTy finally { tbl.Drop(); - } + } } //Data types not supported by FAnsi