From eb932a19111be04915728ba3e04ed5134066141b Mon Sep 17 00:00:00 2001 From: Brice Lambson Date: Mon, 16 Nov 2020 16:18:54 -0800 Subject: [PATCH] Microsoft.Data.Sqlite: Enable nullable reference types Part of #19007 --- .../Extensions/SqliteConnectionExtensions.cs | 4 +- .../Microsoft.Data.Sqlite.Core.csproj | 3 +- .../Properties/Resources.Designer.cs | 18 +- .../Properties/Resources.resx | 6 - src/Microsoft.Data.Sqlite.Core/SqliteBlob.cs | 8 +- .../SqliteCommand.cs | 62 ++---- .../SqliteConnection.CreateAggregate.cs | 206 +++++++++--------- .../SqliteConnection.CreateAggregate.tt | 18 +- .../SqliteConnection.CreateFunction.cs | 142 ++++++------ .../SqliteConnection.CreateFunction.tt | 14 +- .../SqliteConnection.cs | 90 ++++---- .../SqliteConnectionStringBuilder.cs | 23 +- .../SqliteDataReader.cs | 32 +-- .../SqliteDataRecord.cs | 32 ++- .../SqliteException.cs | 6 +- .../SqliteParameter.cs | 15 +- .../SqliteParameterBinder.cs | 4 +- .../SqliteParameterCollection.cs | 15 +- .../SqliteResultBinder.cs | 2 +- .../SqliteTransaction.cs | 44 ++-- .../SqliteValueBinder.cs | 8 +- .../SqliteValueReader.cs | 14 +- .../Utilities/ApplicationDataHelper.cs | 22 +- .../Utilities/BundleInitializer.cs | 5 +- .../Microsoft.Data.Sqlite.csproj | 2 +- .../lib/{netstandard2.0 => net5.0}/_._ | 0 .../Microsoft.Data.Sqlite.Tests.csproj | 1 + ...osoft.Data.Sqlite.e_sqlcipher.Tests.csproj | 1 + ...Microsoft.Data.Sqlite.sqlite3.Tests.csproj | 1 + ...rosoft.Data.Sqlite.winsqlite3.Tests.csproj | 1 + .../SqliteBlobTest.cs | 24 +- .../SqliteCommandTest.cs | 23 +- .../SqliteConnectionTest.cs | 30 ++- .../SqliteDataReaderTest.cs | 50 +++-- .../SqliteParameterTest.cs | 4 +- .../TestUtilities/UseCultureAttribute.cs | 8 +- tools/SqliteResources.tt | 4 +- 37 files changed, 484 insertions(+), 458 deletions(-) rename src/Microsoft.Data.Sqlite/lib/{netstandard2.0 => net5.0}/_._ (100%) diff --git a/src/Microsoft.Data.Sqlite.Core/Extensions/SqliteConnectionExtensions.cs b/src/Microsoft.Data.Sqlite.Core/Extensions/SqliteConnectionExtensions.cs index b44fe2593ca..d2c33dd8d2b 100644 --- a/src/Microsoft.Data.Sqlite.Core/Extensions/SqliteConnectionExtensions.cs +++ b/src/Microsoft.Data.Sqlite.Core/Extensions/SqliteConnectionExtensions.cs @@ -23,9 +23,9 @@ public static T ExecuteScalar( this SqliteConnection connection, string commandText, params SqliteParameter[] parameters) - => (T)connection.ExecuteScalar(commandText, parameters); + => (T)connection.ExecuteScalar(commandText, parameters)!; - private static object ExecuteScalar( + private static object? ExecuteScalar( this SqliteConnection connection, string commandText, params SqliteParameter[] parameters) diff --git a/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj b/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj index a44c5d0d09c..bfd776ea36a 100644 --- a/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj +++ b/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj @@ -15,12 +15,13 @@ Microsoft.Data.Sqlite.SqliteException Microsoft.Data.Sqlite.SqliteFactory Microsoft.Data.Sqlite.SqliteParameter Microsoft.Data.Sqlite.SqliteTransaction - netstandard2.0;net5.0 + net5.0 3.6 true Microsoft.Data.Sqlite.Core.ruleset SQLite;Data;ADO.NET https://docs.microsoft.com/dotnet/standard/data/sqlite/ + enable diff --git a/src/Microsoft.Data.Sqlite.Core/Properties/Resources.Designer.cs b/src/Microsoft.Data.Sqlite.Core/Properties/Resources.Designer.cs index dcd3268fd68..539cf72460f 100644 --- a/src/Microsoft.Data.Sqlite.Core/Properties/Resources.Designer.cs +++ b/src/Microsoft.Data.Sqlite.Core/Properties/Resources.Designer.cs @@ -3,6 +3,8 @@ using System.Reflection; using System.Resources; +#nullable enable + namespace Microsoft.Data.Sqlite.Properties { internal static class Resources @@ -18,14 +20,6 @@ public static string CallRequiresOpenConnection(object methodName) GetString("CallRequiresOpenConnection", nameof(methodName)), methodName); - /// - /// CommandText must be set before {methodName} can be called. - /// - public static string CallRequiresSetCommandText(object methodName) - => string.Format( - GetString("CallRequiresSetCommandText", nameof(methodName)), - methodName); - /// /// ConnectionString cannot be set when the connection is open. /// @@ -86,12 +80,6 @@ public static string MissingParameters(object parameters) public static string NoData => GetString("NoData"); - /// - /// ConnectionString must be set before Open can be called. - /// - public static string OpenRequiresSetConnectionString - => GetString("OpenRequiresSetConnectionString"); - /// /// SqliteConnection does not support nested transactions. /// @@ -254,7 +242,7 @@ public static string EncryptionNotSupported(object libraryName) private static string GetString(string name, params string[] formatterNames) { - var value = _resourceManager.GetString(name); + var value = _resourceManager.GetString(name)!; for (var i = 0; i < formatterNames.Length; i++) { value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); diff --git a/src/Microsoft.Data.Sqlite.Core/Properties/Resources.resx b/src/Microsoft.Data.Sqlite.Core/Properties/Resources.resx index d7940c643b8..12743ff7f8a 100644 --- a/src/Microsoft.Data.Sqlite.Core/Properties/Resources.resx +++ b/src/Microsoft.Data.Sqlite.Core/Properties/Resources.resx @@ -120,9 +120,6 @@ {methodName} can only be called when the connection is open. - - CommandText must be set before {methodName} can be called. - ConnectionString cannot be set when the connection is open. @@ -147,9 +144,6 @@ No data exists for the row/column. - - ConnectionString must be set before Open can be called. - SqliteConnection does not support nested transactions. diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteBlob.cs b/src/Microsoft.Data.Sqlite.Core/SqliteBlob.cs index 656391669ed..20ed6ff975c 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteBlob.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteBlob.cs @@ -16,7 +16,7 @@ namespace Microsoft.Data.Sqlite /// BLOB I/O public class SqliteBlob : Stream { - private sqlite3_blob _blob; + private sqlite3_blob? _blob; private readonly sqlite3 _db; private long _position; @@ -62,17 +62,17 @@ public SqliteBlob( throw new InvalidOperationException(Resources.SqlBlobRequiresOpenConnection); } - if (string.IsNullOrEmpty(tableName)) + if (tableName is null) { throw new ArgumentNullException(nameof(tableName)); } - if (string.IsNullOrEmpty(columnName)) + if (columnName is null) { throw new ArgumentNullException(nameof(columnName)); } - _db = connection.Handle; + _db = connection.Handle!; CanWrite = !readOnly; var rc = sqlite3_blob_open( _db, diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs b/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs index 461455abe85..b398e4de84e 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -23,12 +24,13 @@ namespace Microsoft.Data.Sqlite /// Async Limitations public class SqliteCommand : DbCommand { - private SqliteParameterCollection _parameters; + private SqliteParameterCollection? _parameters; private readonly List _preparedStatements = new List(); - private SqliteConnection _connection; + private SqliteConnection? _connection; private string _commandText = string.Empty; private bool _prepared; + private int? _commandTimeout; /// /// Initializes a new instance of the class. @@ -41,7 +43,7 @@ public SqliteCommand() /// Initializes a new instance of the class. /// /// The SQL to execute against the database. - public SqliteCommand(string commandText) + public SqliteCommand(string? commandText) => CommandText = commandText; /// @@ -49,11 +51,10 @@ public SqliteCommand(string commandText) /// /// The SQL to execute against the database. /// The connection used by the command. - public SqliteCommand(string commandText, SqliteConnection connection) + public SqliteCommand(string? commandText, SqliteConnection? connection) : this(commandText) { Connection = connection; - CommandTimeout = connection.DefaultTimeout; } /// @@ -62,7 +63,7 @@ public SqliteCommand(string commandText, SqliteConnection connection) /// The SQL to execute against the database. /// The connection used by the command. /// The transaction within which the command executes. - public SqliteCommand(string commandText, SqliteConnection connection, SqliteTransaction transaction) + public SqliteCommand(string? commandText, SqliteConnection? connection, SqliteTransaction? transaction) : this(commandText, connection) => Transaction = transaction; @@ -88,6 +89,7 @@ public override CommandType CommandType /// /// The SQL to execute against the database. /// Batching + [AllowNull] public override string CommandText { get => _commandText; @@ -110,7 +112,7 @@ public override string CommandText /// Gets or sets the connection used by the command. /// /// The connection used by the command. - public new virtual SqliteConnection Connection + public new virtual SqliteConnection? Connection { get => _connection; set @@ -135,26 +137,26 @@ public override string CommandText /// Gets or sets the connection used by the command. Must be a . /// /// The connection used by the command. - protected override DbConnection DbConnection + protected override DbConnection? DbConnection { get => Connection; - set => Connection = (SqliteConnection)value; + set => Connection = (SqliteConnection?)value; } /// /// Gets or sets the transaction within which the command executes. /// /// The transaction within which the command executes. - public new virtual SqliteTransaction Transaction { get; set; } + public new virtual SqliteTransaction? Transaction { get; set; } /// /// Gets or sets the transaction within which the command executes. Must be a . /// /// The transaction within which the command executes. - protected override DbTransaction DbTransaction + protected override DbTransaction? DbTransaction { get => Transaction; - set => Transaction = (SqliteTransaction)value; + set => Transaction = (SqliteTransaction?)value; } /// @@ -181,7 +183,11 @@ protected override DbParameterCollection DbParameterCollection /// The timeout is used when the command is waiting to obtain a lock on the table. /// /// Database Errors - public override int CommandTimeout { get; set; } = 30; + public override int CommandTimeout + { + get => _commandTimeout ?? _connection?.DefaultTimeout ?? 30; + set => _commandTimeout = value; + } /// /// Gets or sets a value indicating whether the command should be visible in an interface control. @@ -199,7 +205,7 @@ protected override DbParameterCollection DbParameterCollection /// Gets or sets the data reader currently being used by the command, or null if none. /// /// The data reader currently being used by the command. - protected internal virtual SqliteDataReader DataReader { get; set; } + protected internal virtual SqliteDataReader? DataReader { get; set; } /// /// Releases any resources used by the connection and closes it. @@ -244,11 +250,6 @@ public override void Prepare() throw new InvalidOperationException(Resources.CallRequiresOpenConnection(nameof(Prepare))); } - if (string.IsNullOrEmpty(_commandText)) - { - throw new InvalidOperationException(Resources.CallRequiresSetCommandText(nameof(Prepare))); - } - if (_prepared) { return; @@ -292,11 +293,6 @@ public override void Prepare() throw new InvalidOperationException(Resources.CallRequiresOpenConnection(nameof(ExecuteReader))); } - if (string.IsNullOrEmpty(_commandText)) - { - throw new InvalidOperationException(Resources.CallRequiresSetCommandText(nameof(ExecuteReader))); - } - if (Transaction != _connection.Transaction) { throw new InvalidOperationException( @@ -435,11 +431,6 @@ public override int ExecuteNonQuery() throw new InvalidOperationException(Resources.CallRequiresOpenConnection(nameof(ExecuteNonQuery))); } - if (string.IsNullOrEmpty(_commandText)) - { - throw new InvalidOperationException(Resources.CallRequiresSetCommandText(nameof(ExecuteNonQuery))); - } - var reader = ExecuteReader(); reader.Dispose(); @@ -452,18 +443,13 @@ public override int ExecuteNonQuery() /// The first column of the first row of the results, or null if no results. /// A SQLite error occurs during execution. /// Database Errors - public override object ExecuteScalar() + public override object? ExecuteScalar() { if (_connection?.State != ConnectionState.Open) { throw new InvalidOperationException(Resources.CallRequiresOpenConnection(nameof(ExecuteScalar))); } - if (string.IsNullOrEmpty(_commandText)) - { - throw new InvalidOperationException(Resources.CallRequiresSetCommandText(nameof(ExecuteScalar))); - } - using var reader = ExecuteReader(); return reader.Read() ? reader.GetValue(0) @@ -489,7 +475,7 @@ private IEnumerable PrepareAndEnumerateStatements(Stopwatch timer) timer.Start(); string nextTail; - while (IsBusy(rc = sqlite3_prepare_v2(_connection.Handle, tail, out stmt, out nextTail))) + while (IsBusy(rc = sqlite3_prepare_v2(_connection!.Handle, tail, out stmt, out nextTail))) { if (CommandTimeout != 0 && timer.ElapsedMilliseconds >= CommandTimeout * 1000L) @@ -508,7 +494,7 @@ private IEnumerable PrepareAndEnumerateStatements(Stopwatch timer) // Statement was empty, white space, or a comment if (stmt.IsInvalid) { - if (!string.IsNullOrEmpty(tail)) + if (tail.Length != 0) { continue; } @@ -520,7 +506,7 @@ private IEnumerable PrepareAndEnumerateStatements(Stopwatch timer) yield return stmt; } - while (!string.IsNullOrEmpty(tail)); + while (tail.Length != 0); _prepared = true; } diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.cs b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.cs index e79fa52a4f1..1adf385f4fc 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.cs @@ -4,6 +4,8 @@ using System; +#nullable enable + namespace Microsoft.Data.Sqlite { partial class SqliteConnection @@ -17,8 +19,8 @@ partial class SqliteConnection /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 0, default, IfNotNull(func, (a, r) => func(a)), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 0, default!, IfNotNull(func, (a, r) => func!(a)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -30,8 +32,8 @@ public virtual void CreateAggregate(string name, FuncFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 1, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 1, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -44,8 +46,8 @@ public virtual void CreateAggregate(string name, FuncFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 2, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 2, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -59,8 +61,8 @@ public virtual void CreateAggregate(string name, FuncFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 3, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 3, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -75,8 +77,8 @@ public virtual void CreateAggregate(string name, FuncFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 4, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 4, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -92,8 +94,8 @@ public virtual void CreateAggregate(string name, Fu /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 5, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 5, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -110,8 +112,8 @@ public virtual void CreateAggregate(string name /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 6, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 6, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -129,8 +131,8 @@ public virtual void CreateAggregate(string /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 7, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 7, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -149,8 +151,8 @@ public virtual void CreateAggregate(str /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 8, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 8, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -170,8 +172,8 @@ public virtual void CreateAggregate /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 9, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 9, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -192,8 +194,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 10, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 10, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -215,8 +217,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 11, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 11, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -239,8 +241,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 12, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 12, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -264,8 +266,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 13, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 13, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -290,8 +292,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 14, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 14, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -317,8 +319,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 15, default, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13), r.GetFieldValue(14))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 15, default!, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!, r.GetFieldValue(14)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -329,8 +331,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, -1, default, IfNotNull(func, (a, r) => func(a, GetValues(r))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, -1, default!, IfNotNull(func, (a, r) => func!(a, GetValues(r))), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -342,8 +344,8 @@ public virtual void CreateAggregate(string name, FuncFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 0, seed, IfNotNull(func, (a, r) => func(a)), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 0, seed, IfNotNull(func, (a, r) => func!(a)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -356,8 +358,8 @@ public virtual void CreateAggregate(string name, TAccumulate seed, /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 1, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 1, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -371,8 +373,8 @@ public virtual void CreateAggregate(string name, TAccumulate se /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 2, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 2, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -387,8 +389,8 @@ public virtual void CreateAggregate(string name, TAccumulat /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 3, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 3, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -404,8 +406,8 @@ public virtual void CreateAggregate(string name, TAccum /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 4, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 4, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -422,8 +424,8 @@ public virtual void CreateAggregate(string name, TA /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 5, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 5, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -441,8 +443,8 @@ public virtual void CreateAggregate(string name /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 6, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 6, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -461,8 +463,8 @@ public virtual void CreateAggregate(string /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 7, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 7, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -482,8 +484,8 @@ public virtual void CreateAggregate(str /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 8, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 8, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -504,8 +506,8 @@ public virtual void CreateAggregate /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 9, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 9, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -527,8 +529,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 10, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 10, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -551,8 +553,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 11, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 11, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -576,8 +578,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 12, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 12, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -602,8 +604,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 13, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 13, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -629,8 +631,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 14, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 14, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -657,8 +659,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, 15, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13), r.GetFieldValue(14))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, 15, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!, r.GetFieldValue(14)!)), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -670,8 +672,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, bool isDeterministic = false) - => CreateAggregateCore(name, -1, seed, IfNotNull(func, (a, r) => func(a, GetValues(r))), a => a, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, bool isDeterministic = false) + => CreateAggregateCore(name, -1, seed, IfNotNull(func, (a, r) => func!(a, GetValues(r))), a => a, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -688,8 +690,8 @@ public virtual void CreateAggregate(string name, TAccumulate seed, /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 0, seed, IfNotNull(func, (a, r) => func(a)), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 0, seed, IfNotNull(func, (a, r) => func!(a)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -707,8 +709,8 @@ public virtual void CreateAggregate(string name, TAccumula /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 1, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 1, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -727,8 +729,8 @@ public virtual void CreateAggregate(string name, TAccu /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 2, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 2, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -748,8 +750,8 @@ public virtual void CreateAggregate(string name, T /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 3, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 3, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -770,8 +772,8 @@ public virtual void CreateAggregate(string nam /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 4, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 4, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -793,8 +795,8 @@ public virtual void CreateAggregate(string /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 5, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 5, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -817,8 +819,8 @@ public virtual void CreateAggregate(st /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 6, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 6, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -842,8 +844,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 7, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 7, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -868,8 +870,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 8, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 8, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -895,8 +897,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 9, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 9, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -923,8 +925,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 10, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 10, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -952,8 +954,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 11, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 11, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -982,8 +984,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 12, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 12, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -1013,8 +1015,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 13, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 13, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -1045,8 +1047,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 14, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 14, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -1078,8 +1080,8 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, 15, seed, IfNotNull(func, (a, r) => func(a, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13), r.GetFieldValue(14))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, 15, seed, IfNotNull(func, (a, r) => func!(a, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!, r.GetFieldValue(14)!)), resultSelector, isDeterministic); /// /// Creates or redefines an aggregate SQL function. @@ -1096,7 +1098,7 @@ public virtual void CreateAggregateFlag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate(string name, TAccumulate seed, Func func, Func resultSelector, bool isDeterministic = false) - => CreateAggregateCore(name, -1, seed, IfNotNull(func, (a, r) => func(a, GetValues(r))), resultSelector, isDeterministic); + public virtual void CreateAggregate(string name, TAccumulate seed, Func? func, Func? resultSelector, bool isDeterministic = false) + => CreateAggregateCore(name, -1, seed, IfNotNull(func, (a, r) => func!(a, GetValues(r))), resultSelector, isDeterministic); } } diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.tt b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.tt index b59a90e37e6..6cf18274173 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.tt +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateAggregate.tt @@ -7,6 +7,8 @@ using System; +#nullable enable + namespace Microsoft.Data.Sqlite { partial class SqliteConnection @@ -22,7 +24,7 @@ namespace Microsoft.Data.Sqlite : ""; var resultSelectorParameter = resultSelector - ? ", Func resultSelector" + ? ", Func? resultSelector" : ""; var resultSelectorArgument = resultSelector @@ -42,7 +44,7 @@ namespace Microsoft.Data.Sqlite var seedArgument = seed ? "seed" - : "default"; + : "default!"; for (var arity = 0; arity <= 15; arity++) { @@ -60,7 +62,7 @@ namespace Microsoft.Data.Sqlite var typeArguments = String.Join(", ", typeArgumentsList); var lambdaTypeArgumentList = new List(); - lambdaTypeArgumentList.Add("TAccumulate"); + lambdaTypeArgumentList.Add("TAccumulate" + (seed ? "" : "?")); lambdaTypeArgumentList.AddRange(parameterTypeArgumentList); lambdaTypeArgumentList.Add("TAccumulate"); @@ -72,7 +74,7 @@ namespace Microsoft.Data.Sqlite for (var i = 0; i < parameterTypeArgumentList.Count; i++) { - lambdaArgumentsList.Add("r.GetFieldValue<" + parameterTypeArgumentList[i] + ">(" + i + ")"); + lambdaArgumentsList.Add("r.GetFieldValue<" + parameterTypeArgumentList[i] + ">(" + i + ")!"); } var lambdaArguments = string.Join(", ", lambdaArgumentsList); @@ -110,8 +112,8 @@ namespace Microsoft.Data.Sqlite /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate<<#= typeArguments #>>(string name<#= seedParameter #>, Func<<#= lambdaTypeArguments #>> func<#= resultSelectorParameter #>, bool isDeterministic = false) - => CreateAggregateCore(name, <#= arity #>, <#= seedArgument #>, IfNotNull(func, (a, r) => func(<#= lambdaArguments #>)), <#= resultSelectorArgument #>, isDeterministic); + public virtual void CreateAggregate<<#= typeArguments #>>(string name<#= seedParameter #>, Func<<#= lambdaTypeArguments #>>? func<#= resultSelectorParameter #>, bool isDeterministic = false) + => CreateAggregateCore(name, <#= arity #>, <#= seedArgument #>, IfNotNull, TAccumulate>(func, (a, r) => func!(<#= lambdaArguments #>)), <#= resultSelectorArgument #>, isDeterministic); <# } #> @@ -137,8 +139,8 @@ namespace Microsoft.Data.Sqlite /// Flag indicating whether the aggregate is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateAggregate>(string name<#= seedParameter #>, Func func<#= resultSelectorParameter #>, bool isDeterministic = false) - => CreateAggregateCore(name, -1, <#= seedArgument #>, IfNotNull(func, (a, r) => func(a, GetValues(r))), <#= resultSelectorArgument #>, isDeterministic); + public virtual void CreateAggregate>(string name<#= seedParameter #>, Func, object?[], TAccumulate>? func<#= resultSelectorParameter #>, bool isDeterministic = false) + => CreateAggregateCore(name, -1, <#= seedArgument #>, IfNotNull, TAccumulate>(func, (a, r) => func!(a, GetValues(r))), <#= resultSelectorArgument #>, isDeterministic); <# } } diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.cs b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.cs index 3b563950e97..facf5448d44 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.cs @@ -4,6 +4,8 @@ using System; +#nullable enable + namespace Microsoft.Data.Sqlite { partial class SqliteConnection @@ -17,8 +19,8 @@ partial class SqliteConnection /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 0, null, IfNotNull(function, (s, r) => function()), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 0, null, IfNotNull(function, (s, r) => function!()), isDeterministic); /// /// Creates or redefines a SQL function. @@ -30,8 +32,8 @@ public virtual void CreateFunction(string name, Func function, /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 1, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 1, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -44,8 +46,8 @@ public virtual void CreateFunction(string name, Func f /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 2, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 2, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -59,8 +61,8 @@ public virtual void CreateFunction(string name, FuncFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 3, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 3, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -75,8 +77,8 @@ public virtual void CreateFunction(string name, FuncFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 4, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 4, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -92,8 +94,8 @@ public virtual void CreateFunction(string name, FuncFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 5, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 5, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -110,8 +112,8 @@ public virtual void CreateFunction(string name, Fun /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 6, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 6, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -129,8 +131,8 @@ public virtual void CreateFunction(string name, /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 7, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 7, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -149,8 +151,8 @@ public virtual void CreateFunction(string n /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 8, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 8, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -170,8 +172,8 @@ public virtual void CreateFunction(stri /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 9, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 9, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -192,8 +194,8 @@ public virtual void CreateFunction( /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 10, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 10, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -215,8 +217,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 11, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 11, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -239,8 +241,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 12, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 12, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -264,8 +266,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 13, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 13, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -290,8 +292,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 14, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 14, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -317,8 +319,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 15, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13), r.GetFieldValue(14))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 15, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!, r.GetFieldValue(14)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -345,8 +347,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 16, null, IfNotNull(function, (s, r) => function(r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13), r.GetFieldValue(14), r.GetFieldValue(15))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 16, null, IfNotNull(function, (s, r) => function!(r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!, r.GetFieldValue(14)!, r.GetFieldValue(15)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -357,8 +359,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, -1, null, IfNotNull(function, (s, r) => function(GetValues(r))), isDeterministic); + public virtual void CreateFunction(string name, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, -1, null, IfNotNull(function, (s, r) => function!(GetValues(r))), isDeterministic); /// /// Creates or redefines a SQL function. @@ -371,8 +373,8 @@ public virtual void CreateFunction(string name, Func /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 0, state, IfNotNull(function, (s, r) => function(s)), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 0, state, IfNotNull(function, (s, r) => function!(s)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -386,8 +388,8 @@ public virtual void CreateFunction(string name, TState state, F /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 1, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 1, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -402,8 +404,8 @@ public virtual void CreateFunction(string name, TState stat /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 2, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 2, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -419,8 +421,8 @@ public virtual void CreateFunction(string name, TState /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 3, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 3, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -437,8 +439,8 @@ public virtual void CreateFunction(string name, TSt /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 4, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 4, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -456,8 +458,8 @@ public virtual void CreateFunction(string name, /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 5, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 5, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -476,8 +478,8 @@ public virtual void CreateFunction(string n /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 6, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 6, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -497,8 +499,8 @@ public virtual void CreateFunction(stri /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 7, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 7, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -519,8 +521,8 @@ public virtual void CreateFunction( /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 8, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 8, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -542,8 +544,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 9, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 9, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -566,8 +568,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 10, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 10, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -591,8 +593,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 11, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 11, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -617,8 +619,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 12, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 12, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -644,8 +646,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 13, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 13, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -672,8 +674,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 14, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 14, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -701,8 +703,8 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, 15, state, IfNotNull(function, (s, r) => function(s, r.GetFieldValue(0), r.GetFieldValue(1), r.GetFieldValue(2), r.GetFieldValue(3), r.GetFieldValue(4), r.GetFieldValue(5), r.GetFieldValue(6), r.GetFieldValue(7), r.GetFieldValue(8), r.GetFieldValue(9), r.GetFieldValue(10), r.GetFieldValue(11), r.GetFieldValue(12), r.GetFieldValue(13), r.GetFieldValue(14))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, 15, state, IfNotNull(function, (s, r) => function!(s, r.GetFieldValue(0)!, r.GetFieldValue(1)!, r.GetFieldValue(2)!, r.GetFieldValue(3)!, r.GetFieldValue(4)!, r.GetFieldValue(5)!, r.GetFieldValue(6)!, r.GetFieldValue(7)!, r.GetFieldValue(8)!, r.GetFieldValue(9)!, r.GetFieldValue(10)!, r.GetFieldValue(11)!, r.GetFieldValue(12)!, r.GetFieldValue(13)!, r.GetFieldValue(14)!)), isDeterministic); /// /// Creates or redefines a SQL function. @@ -715,7 +717,7 @@ public virtual void CreateFunctionFlag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction(string name, TState state, Func function, bool isDeterministic = false) - => CreateFunctionCore(name, -1, state, IfNotNull(function, (s, r) => function(s, GetValues(r))), isDeterministic); + public virtual void CreateFunction(string name, TState state, Func? function, bool isDeterministic = false) + => CreateFunctionCore(name, -1, state, IfNotNull(function, (s, r) => function!(s, GetValues(r))), isDeterministic); } } diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.tt b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.tt index 9ea95e29083..41bdc399ddc 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.tt +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.CreateFunction.tt @@ -7,6 +7,8 @@ using System; +#nullable enable + namespace Microsoft.Data.Sqlite { partial class SqliteConnection @@ -35,7 +37,7 @@ namespace Microsoft.Data.Sqlite var stateParameterType = state ? "TState" - : "object"; + : "object?"; var lambdaStateArgument = state ? "s, " @@ -66,7 +68,7 @@ namespace Microsoft.Data.Sqlite for (var i = 0; i < parameterTypeArgumentList.Count; i++) { - lambdaArgumentsList.Add("r.GetFieldValue<" + parameterTypeArgumentList[i] + ">(" + i + ")"); + lambdaArgumentsList.Add("r.GetFieldValue<" + parameterTypeArgumentList[i] + ">(" + i + ")!"); } var lambdaArguments = string.Join(", ", lambdaArgumentsList); @@ -98,8 +100,8 @@ namespace Microsoft.Data.Sqlite /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction<<#= typeArguments #>>(string name, <#= stateParameter #>Func<<#= typeArguments #>> function, bool isDeterministic = false) - => CreateFunctionCore(name, <#= arity #>, <#= stateArgument #>, IfNotNull<<#= stateParameterType #>, TResult>(function, (s, r) => function(<#= lambdaArguments #>)), isDeterministic); + public virtual void CreateFunction<<#= typeArguments #>>(string name, <#= stateParameter #>Func<<#= typeArguments #>>? function, bool isDeterministic = false) + => CreateFunctionCore(name, <#= arity #>, <#= stateArgument #>, IfNotNull<<#= stateParameterType #>, TResult>(function, (s, r) => function!(<#= lambdaArguments #>)), isDeterministic); <# } @@ -120,8 +122,8 @@ namespace Microsoft.Data.Sqlite /// Flag indicating whether the function is deterministic. /// User-Defined Functions /// Data Types - public virtual void CreateFunction<<#= stateTypeArgument #>TResult>(string name, <#= stateParameter #>Func<<#= stateTypeArgument #>object[], TResult> function, bool isDeterministic = false) - => CreateFunctionCore(name, -1, <#= stateArgument #>, IfNotNull<<#= stateParameterType #>, TResult>(function, (s, r) => function(<#= lambdaStateArgument #>GetValues(r))), isDeterministic); + public virtual void CreateFunction<<#= stateTypeArgument #>TResult>(string name, <#= stateParameter #>Func<<#= stateTypeArgument #>object?[], TResult>? function, bool isDeterministic = false) + => CreateFunctionCore(name, -1, <#= stateArgument #>, IfNotNull<<#= stateParameterType #>, TResult>(function, (s, r) => function!(<#= lambdaStateArgument #>GetValues(r))), isDeterministic); <# } #> diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs index faafbc80b07..1337127eac8 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs @@ -6,6 +6,7 @@ using System.Data; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using Microsoft.Data.Sqlite.Properties; using Microsoft.Data.Sqlite.Utilities; @@ -27,19 +28,21 @@ public partial class SqliteConnection : DbConnection private readonly List> _commands = new List>(); - private Dictionary _collations; + private Dictionary? _collations; - private Dictionary<(string name, int arity), (int flags, object state, delegate_function_scalar func)> _functions; + private Dictionary<(string name, int arity), (int flags, object? state, delegate_function_scalar? func)>? _functions; - private Dictionary<(string name, int arity), (int flags, object state, delegate_function_aggregate_step func_step, - delegate_function_aggregate_final func_final)> _aggregates; + private Dictionary<(string name, int arity), (int flags, object? state, delegate_function_aggregate_step? func_step, + delegate_function_aggregate_final? func_final)>? _aggregates; - private HashSet<(string file, string proc)> _extensions; + private HashSet<(string file, string? proc)>? _extensions; private string _connectionString = string.Empty; + private SqliteConnectionStringBuilder? _connectionOptions; private ConnectionState _state; - private sqlite3 _db; + private sqlite3? _db; private bool _extensionsEnabled; + private int? _defaultTimeout; static SqliteConnection() => BundleInitializer.Initialize(); @@ -57,7 +60,7 @@ public SqliteConnection() /// The string used to open the connection. /// Connection Strings /// - public SqliteConnection(string connectionString) + public SqliteConnection(string? connectionString) => ConnectionString = connectionString; /// @@ -65,7 +68,7 @@ public SqliteConnection(string connectionString) /// /// A handle to underlying database connection. /// Interoperability - public virtual sqlite3 Handle + public virtual sqlite3? Handle => _db; /// @@ -74,6 +77,7 @@ public virtual sqlite3 Handle /// A string used to open the connection. /// Connection Strings /// + [AllowNull] public override string ConnectionString { get => _connectionString; @@ -85,11 +89,12 @@ public override string ConnectionString } _connectionString = value ?? string.Empty; - ConnectionOptions = new SqliteConnectionStringBuilder(value); + _connectionOptions = null; } } - internal SqliteConnectionStringBuilder ConnectionOptions { get; set; } + internal SqliteConnectionStringBuilder ConnectionOptions + => _connectionOptions ??= new SqliteConnectionStringBuilder(ConnectionString); /// /// Gets the name of the current database. Always 'main'. @@ -106,7 +111,7 @@ public override string DataSource { get { - string dataSource = null; + string? dataSource = null; if (State == ConnectionState.Open) { dataSource = sqlite3_db_filename(_db, MainDatabaseName).utf8_to_string(); @@ -123,7 +128,11 @@ public override string DataSource /// /// The default value. /// Database Errors - public virtual int DefaultTimeout { get; set; } = 30; + public virtual int DefaultTimeout + { + get => _defaultTimeout ?? 30; + set => _defaultTimeout = value; + } /// /// Gets the version of SQLite used by the connection. @@ -150,7 +159,7 @@ protected override DbProviderFactory DbProviderFactory /// Gets or sets the transaction currently being used by the connection, or null if none. /// /// The transaction currently being used by the connection. - protected internal virtual SqliteTransaction Transaction { get; set; } + protected internal virtual SqliteTransaction? Transaction { get; set; } /// /// Opens a connection to the database using the value of . If @@ -164,11 +173,6 @@ public override void Open() return; } - if (string.IsNullOrEmpty(ConnectionString)) - { - throw new InvalidOperationException(Resources.OpenRequiresSetConnectionString); - } - var filename = ConnectionOptions.DataSource; var flags = 0; @@ -243,7 +247,7 @@ public override void Open() _state = ConnectionState.Open; try { - if (!string.IsNullOrEmpty(ConnectionOptions.Password)) + if (ConnectionOptions.Password.Length != 0) { if (SQLitePCLExtensions.EncryptionSupported(out var libraryName) == false) { @@ -364,7 +368,7 @@ public override void Close() Debug.Assert(_commands.Count == 0); - _db.Dispose(); + _db!.Dispose(); _db = null; _state = ConnectionState.Closed; @@ -432,9 +436,9 @@ internal void RemoveCommand(SqliteCommand command) /// Name of the collation. /// Method that compares two strings. /// Collation - public virtual void CreateCollation(string name, Comparison comparison) + public virtual void CreateCollation(string name, Comparison? comparison) => CreateCollation( - name, null, comparison != null ? (_, s1, s2) => comparison(s1, s2) : (Func)null); + name, null, comparison != null ? (_, s1, s2) => comparison(s1, s2) : (Func?)null); /// /// Create custom collation. @@ -444,14 +448,14 @@ public virtual void CreateCollation(string name, Comparison comparison) /// State object passed to each invocation of the collation. /// Method that compares two strings, using additional state. /// Collation - public virtual void CreateCollation(string name, T state, Func comparison) + public virtual void CreateCollation(string name, T state, Func? comparison) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name)); } - var collation = comparison != null ? (v, s1, s2) => comparison((T)v, s1, s2) : (strdelegate_collation)null; + var collation = comparison != null ? (v, s1, s2) => comparison((T)v, s1, s2) : (strdelegate_collation?)null; if (State == ConnectionState.Open) { @@ -459,7 +463,7 @@ public virtual void CreateCollation(string name, T state, Func(StringComparer.OrdinalIgnoreCase); + _collations ??= new Dictionary(StringComparer.OrdinalIgnoreCase); _collations[name] = (state, collation); } @@ -575,7 +579,7 @@ public virtual void EnableExtensions(bool enable = true) /// The shared library containing the extension. /// The entry point. If null, the default entry point is used. /// Extensions - public virtual void LoadExtension(string file, string proc = null) + public virtual void LoadExtension(string file, string? proc = null) { if (State == ConnectionState.Open) { @@ -598,11 +602,11 @@ public virtual void LoadExtension(string file, string proc = null) } } - _extensions ??= new HashSet<(string, string)>(); + _extensions ??= new HashSet<(string, string?)>(); _extensions.Add((file, proc)); } - private void LoadExtensionCore(string file, string proc) + private void LoadExtensionCore(string file, string? proc) { if (proc == null) { @@ -680,15 +684,15 @@ private void CreateFunctionCore( string name, int arity, TState state, - Func function, + Func? function, bool isDeterministic) { - if (string.IsNullOrEmpty(name)) + if (name == null) { throw new ArgumentNullException(nameof(name)); } - delegate_function_scalar func = null; + delegate_function_scalar? func = null; if (function != null) { func = (ctx, user_data, args) => @@ -730,7 +734,7 @@ private void CreateFunctionCore( SqliteException.ThrowExceptionForRC(rc, _db); } - _functions ??= new Dictionary<(string, int), (int, object, delegate_function_scalar)>(FunctionsKeyComparer.Instance); + _functions ??= new Dictionary<(string, int), (int, object?, delegate_function_scalar?)>(FunctionsKeyComparer.Instance); _functions[(name, arity)] = (flags, state, func); } @@ -738,16 +742,16 @@ private void CreateAggregateCore( string name, int arity, TAccumulate seed, - Func func, - Func resultSelector, + Func? func, + Func? resultSelector, bool isDeterministic) { - if (string.IsNullOrEmpty(name)) + if (name == null) { throw new ArgumentNullException(nameof(name)); } - delegate_function_aggregate_step func_step = null; + delegate_function_aggregate_step? func_step = null; if (func != null) { func_step = (ctx, user_data, args) => @@ -774,7 +778,7 @@ private void CreateAggregateCore( }; } - delegate_function_aggregate_final func_final = null; + delegate_function_aggregate_final? func_final = null; if (resultSelector != null) { func_final = (ctx, user_data) => @@ -826,19 +830,19 @@ private void CreateAggregateCore( } _aggregates ??= - new Dictionary<(string, int), (int, object, delegate_function_aggregate_step, delegate_function_aggregate_final)>( + new Dictionary<(string, int), (int, object?, delegate_function_aggregate_step?, delegate_function_aggregate_final?)>( FunctionsKeyComparer.Instance); _aggregates[(name, arity)] = (flags, state, func_step, func_final); } - private static Func IfNotNull( - object x, + private static Func? IfNotNull( + object? x, Func value) => x != null ? value : null; - private static object[] GetValues(SqliteValueReader reader) + private static object?[] GetValues(SqliteValueReader reader) { - var values = new object[reader.FieldCount]; + var values = new object?[reader.FieldCount]; reader.GetValues(values); return values; @@ -850,7 +854,7 @@ public AggregateContext(T seed) => Accumulate = seed; public T Accumulate { get; set; } - public Exception Exception { get; set; } + public Exception? Exception { get; set; } } private sealed class FunctionsKeyComparer : IEqualityComparer<(string name, int arity)> diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnectionStringBuilder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteConnectionStringBuilder.cs index 58d58bb37b7..e19252c2365 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnectionStringBuilder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnectionStringBuilder.cs @@ -7,6 +7,7 @@ using System.Collections.ObjectModel; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using Microsoft.Data.Sqlite.Properties; @@ -87,17 +88,18 @@ public SqliteConnectionStringBuilder() /// /// The initial connection string the builder will represent. Can be null. /// - public SqliteConnectionStringBuilder(string connectionString) + public SqliteConnectionStringBuilder(string? connectionString) => ConnectionString = connectionString; /// /// Gets or sets the database file. /// /// The database file. + [AllowNull] public virtual string DataSource { get => _dataSource; - set => base[DataSourceKeyword] = _dataSource = value; + set => base[DataSourceKeyword] = _dataSource = value ?? string.Empty; } /// @@ -125,13 +127,13 @@ public override ICollection Values { get { - var values = new object[_validKeywords.Count]; + var values = new object?[_validKeywords.Count]; for (var i = 0; i < _validKeywords.Count; i++) { values[i] = GetAt((Keywords)i); } - return new ReadOnlyCollection(values); + return new ReadOnlyCollection(values); } } @@ -151,10 +153,11 @@ public virtual SqliteCacheMode Cache /// /// The encryption key. /// Encryption + [AllowNull] public string Password { get => _password; - set => base[PasswordKeyword] = _password = value; + set => base[PasswordKeyword] = _password = value ?? string.Empty; } /// @@ -187,9 +190,11 @@ public bool RecursiveTriggers /// /// The key. /// The value. - public override object this[string keyword] + public override object? this[string keyword] { +#pragma warning disable CS8764 // NB: this["Foreign Keys"] may return null get => GetAt(GetIndex(keyword)); +#pragma warning restore CS8764 set { if (value == null) @@ -329,7 +334,9 @@ public override bool ShouldSerialize(string keyword) /// The key. /// The value. /// if the key was used; otherwise, . - public override bool TryGetValue(string keyword, out object value) +#pragma warning disable CS8765 // NB: TryGetValue("Foreign Keys", out value) returns true, but value may be null + public override bool TryGetValue(string keyword, out object? value) +#pragma warning restore CS8765 { if (!_keywords.TryGetValue(keyword, out var index)) { @@ -343,7 +350,7 @@ public override bool TryGetValue(string keyword, out object value) return true; } - private object GetAt(Keywords index) + private object? GetAt(Keywords index) { switch (index) { diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs b/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs index c9affe02ea7..6e93c53649b 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteDataReader.cs @@ -25,8 +25,8 @@ public class SqliteDataReader : DbDataReader private readonly SqliteCommand _command; private readonly bool _closeConnection; private readonly Stopwatch _timer; - private IEnumerator _stmtEnumerator; - private SqliteDataRecord _record; + private IEnumerator? _stmtEnumerator; + private SqliteDataRecord? _record; private bool _closed; private int _recordsAffected = -1; @@ -63,7 +63,7 @@ public override int FieldCount /// /// A handle to underlying prepared statement. /// Interoperability - public virtual sqlite3_stmt Handle + public virtual sqlite3_stmt? Handle => _record?.Handle; /// @@ -148,7 +148,7 @@ public override bool NextResult() sqlite3_stmt stmt; int rc; - while (_stmtEnumerator.MoveNext()) + while (_stmtEnumerator!.MoveNext()) { try { @@ -172,7 +172,7 @@ public override bool NextResult() _timer.Stop(); - SqliteException.ThrowExceptionForRC(rc, _command.Connection.Handle); + SqliteException.ThrowExceptionForRC(rc, _command.Connection!.Handle); // It's a SELECT statement if (sqlite3_column_count(stmt) != 0) @@ -249,7 +249,7 @@ protected override void Dispose(bool disposing) { while (NextResult()) { - _record.Dispose(); + _record!.Dispose(); } } catch @@ -263,7 +263,7 @@ protected override void Dispose(bool disposing) if (_closeConnection) { - _command.Connection.Close(); + _command.Connection!.Close(); } } @@ -507,7 +507,7 @@ public override string GetString(int ordinal) /// The index to which the data will be copied. /// The maximum number of bytes to read. /// The actual number of bytes read. - public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) + public override long GetBytes(int ordinal, long dataOffset, byte[]? buffer, int bufferOffset, int length) => _closed ? throw new InvalidOperationException(Resources.DataReaderClosed(nameof(GetBytes))) : _record == null @@ -523,7 +523,7 @@ public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int b /// The index to which the data will be copied. /// The maximum number of characters to read. /// The actual number of characters read. - public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) + public override long GetChars(int ordinal, long dataOffset, char[]? buffer, int bufferOffset, int length) => _closed ? throw new InvalidOperationException(Resources.DataReaderClosed(nameof(GetChars))) : _record == null @@ -588,7 +588,7 @@ public override object GetValue(int ordinal) /// An array into which the values are copied. /// The number of values copied into the array. /// Data Types - public override int GetValues(object[] values) + public override int GetValues(object?[] values) => _closed ? throw new InvalidOperationException(Resources.DataReaderClosed(nameof(GetValues))) : _record == null @@ -669,7 +669,7 @@ public override DataTable GetSchemaTable() schemaRow[ColumnSize] = -1; schemaRow[NumericPrecision] = DBNull.Value; schemaRow[NumericScale] = DBNull.Value; - schemaRow[BaseServerName] = _command.Connection.DataSource; + schemaRow[BaseServerName] = _command.Connection!.DataSource; var databaseName = sqlite3_column_database_name(_record.Handle, i).utf8_to_string(); schemaRow[BaseCatalogName] = databaseName; var columnName = sqlite3_column_origin_name(_record.Handle, i).utf8_to_string(); @@ -684,8 +684,8 @@ public override DataTable GetSchemaTable() schemaRow[IsExpression] = columnName == null; schemaRow[IsLong] = DBNull.Value; - if (!string.IsNullOrEmpty(tableName) - && !string.IsNullOrEmpty(columnName)) + if (tableName != null + && columnName != null) { using (var command = _command.Connection.CreateCommand()) { @@ -697,7 +697,7 @@ public override DataTable GetSchemaTable() command.Parameters.AddWithValue("$table", tableName); command.Parameters.AddWithValue("$column", columnName); - var cnt = (long)command.ExecuteScalar(); + var cnt = (long)command.ExecuteScalar()!; schemaRow[IsUnique] = cnt != 0; command.Parameters.Clear(); @@ -710,7 +710,7 @@ public override DataTable GetSchemaTable() .AppendLine("ORDER BY count() DESC") .AppendLine("LIMIT 1;").ToString(); - var type = (string)command.ExecuteScalar(); + var type = (string)command.ExecuteScalar()!; schemaRow[DataType] = (type != null) ? SqliteDataRecord.GetFieldType(type) @@ -718,7 +718,7 @@ public override DataTable GetSchemaTable() SqliteDataRecord.Sqlite3AffinityType(dataTypeName)); } - if (!string.IsNullOrEmpty(databaseName)) + if (databaseName != null) { var rc = sqlite3_table_column_metadata( _command.Connection.Handle, databaseName, tableName, columnName, out var dataType, out var collSeq, diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs b/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs index 7af9cbc0fcd..e74006d4d39 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs @@ -15,8 +15,8 @@ namespace Microsoft.Data.Sqlite internal class SqliteDataRecord : SqliteValueReader, IDisposable { private readonly SqliteConnection _connection; - private byte[][] _blobCache; - private int?[] _typeCache; + private byte[][]? _blobCache; + private int?[]? _typeCache; private bool _stepped; private int? _rowidOrdinal; @@ -48,7 +48,7 @@ public override bool IsDBNull(int ordinal) public override object GetValue(int ordinal) => !_stepped || sqlite3_data_count(Handle) == 0 ? throw new InvalidOperationException(Resources.NoData) - : base.GetValue(ordinal); + : base.GetValue(ordinal)!; protected override double GetDoubleCore(int ordinal) => sqlite3_column_double(Handle, ordinal); @@ -59,6 +59,12 @@ protected override long GetInt64Core(int ordinal) protected override string GetStringCore(int ordinal) => sqlite3_column_text(Handle, ordinal).utf8_to_string(); + public override T GetFieldValue(int ordinal) + => base.GetFieldValue(ordinal)!; + + protected override byte[] GetBlob(int ordinal) + => base.GetBlob(ordinal)!; + protected override byte[] GetBlobCore(int ordinal) => sqlite3_column_blob(Handle, ordinal).ToArray(); @@ -90,7 +96,7 @@ public virtual string GetName(int ordinal) throw new ArgumentOutOfRangeException(nameof(ordinal), ordinal, message: null); } - return name; + return name!; } public virtual int GetOrdinal(string name) @@ -195,13 +201,13 @@ public static Type GetFieldType(string type) } } - public virtual long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) + public virtual long GetBytes(int ordinal, long dataOffset, byte[]? buffer, int bufferOffset, int length) { using var stream = GetStream(ordinal); if (buffer == null) { - return stream.Length - dataOffset; + return stream.Length; } stream.Position = dataOffset; @@ -209,10 +215,22 @@ public virtual long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bu return stream.Read(buffer, bufferOffset, length); } - public virtual long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) + public virtual long GetChars(int ordinal, long dataOffset, char[]? buffer, int bufferOffset, int length) { using var reader = new StreamReader(GetStream(ordinal), Encoding.UTF8); + if (buffer == null) + { + // TODO: Consider using a stackalloc buffer and reading blocks instead + var charCount = 0; + while (reader.Read() != -1) + { + charCount++; + } + + return charCount; + } + for (var position = 0; position < dataOffset; position++) { if (reader.Read() == -1) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteException.cs b/src/Microsoft.Data.Sqlite.Core/SqliteException.cs index 6837a09cc84..b27a7c24b63 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteException.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteException.cs @@ -19,7 +19,7 @@ public class SqliteException : DbException /// /// The message to display for the exception. Can be null. /// The SQLite error code. - public SqliteException(string message, int errorCode) + public SqliteException(string? message, int errorCode) : this(message, errorCode, errorCode) { } @@ -30,7 +30,7 @@ public SqliteException(string message, int errorCode) /// The message to display for the exception. Can be null. /// The SQLite error code. /// The extended SQLite error code. - public SqliteException(string message, int errorCode, int extendedErrorCode) + public SqliteException(string? message, int errorCode, int extendedErrorCode) : base(message) { SqliteErrorCode = errorCode; @@ -59,7 +59,7 @@ public SqliteException(string message, int errorCode, int extendedErrorCode) /// /// No exception is thrown for non-error result codes. /// - public static void ThrowExceptionForRC(int rc, sqlite3 db) + public static void ThrowExceptionForRC(int rc, sqlite3? db) { if (rc == SQLITE_OK || rc == SQLITE_ROW diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs b/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs index 597db1e24f3..ea2910139fa 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteParameter.cs @@ -4,6 +4,7 @@ using System; using System.Data; using System.Data.Common; +using System.Diagnostics.CodeAnalysis; using Microsoft.Data.Sqlite.Properties; using SQLitePCL; using static SQLitePCL.raw; @@ -19,7 +20,7 @@ namespace Microsoft.Data.Sqlite public class SqliteParameter : DbParameter { private string _parameterName = string.Empty; - private object _value; + private object? _value; private int? _size; private SqliteType? _sqliteType; private string _sourceColumn = string.Empty; @@ -39,7 +40,7 @@ public SqliteParameter() /// The value of the parameter. Can be null. /// Parameters /// Data Types - public SqliteParameter(string name, object value) + public SqliteParameter(string? name, object? value) { ParameterName = name; Value = value; @@ -51,7 +52,7 @@ public SqliteParameter(string name, object value) /// The name of the parameter. /// The type of the parameter. /// Parameters - public SqliteParameter(string name, SqliteType type) + public SqliteParameter(string? name, SqliteType type) { ParameterName = name; SqliteType = type; @@ -64,7 +65,7 @@ public SqliteParameter(string name, SqliteType type) /// The type of the parameter. /// The maximum size, in bytes, of the parameter. /// Parameters - public SqliteParameter(string name, SqliteType type, int size) + public SqliteParameter(string? name, SqliteType type, int size) : this(name, type) => Size = size; @@ -76,7 +77,7 @@ public SqliteParameter(string name, SqliteType type, int size) /// The maximum size, in bytes, of the parameter. /// The source column used for loading the value. Can be null. /// Parameters - public SqliteParameter(string name, SqliteType type, int size, string sourceColumn) + public SqliteParameter(string? name, SqliteType type, int size, string? sourceColumn) : this(name, type, size) => SourceColumn = sourceColumn; @@ -124,6 +125,7 @@ public override ParameterDirection Direction /// Gets or sets the name of the parameter. /// /// The name of the parameter. + [AllowNull] public override string ParameterName { get => _parameterName; @@ -161,6 +163,7 @@ public override int Size /// Gets or sets the source column used for loading the value. /// /// The source column used for loading the value. + [AllowNull] public override string SourceColumn { get => _sourceColumn; @@ -179,7 +182,7 @@ public override string SourceColumn /// The value of the parameter. /// Due to SQLite's dynamic type system, parameter values are not converted. /// Data Types - public override object Value + public override object? Value { get => _value; set { _value = value; } diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteParameterBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteParameterBinder.cs index 2809de826d1..c4376d24f89 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteParameterBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteParameterBinder.cs @@ -26,7 +26,7 @@ protected override void BindBlob(byte[] value) var blob = value; if (ShouldTruncate(value.Length)) { - blob = new byte[_size.Value]; + blob = new byte[_size!.Value]; Array.Copy(value, blob, _size.Value); } @@ -47,7 +47,7 @@ protected override void BindText(string value) _stmt, _index, ShouldTruncate(value.Length) - ? value.Substring(0, _size.Value) + ? value.Substring(0, _size!.Value) : value); private bool ShouldTruncate(int length) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteParameterCollection.cs b/src/Microsoft.Data.Sqlite.Core/SqliteParameterCollection.cs index f4f81a7c52d..24c5e9ebfc8 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteParameterCollection.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteParameterCollection.cs @@ -103,7 +103,7 @@ public virtual SqliteParameter Add(SqliteParameter value) /// The SQLite type of the parameter. /// The parameter that was added. /// Parameters - public virtual SqliteParameter Add(string parameterName, SqliteType type) + public virtual SqliteParameter Add(string? parameterName, SqliteType type) => Add(new SqliteParameter(parameterName, type)); /// @@ -114,7 +114,7 @@ public virtual SqliteParameter Add(string parameterName, SqliteType type) /// The maximum size, in bytes, of the parameter. /// The parameter that was added. /// Parameters - public virtual SqliteParameter Add(string parameterName, SqliteType type, int size) + public virtual SqliteParameter Add(string? parameterName, SqliteType type, int size) => Add(new SqliteParameter(parameterName, type, size)); /// @@ -128,7 +128,7 @@ public virtual SqliteParameter Add(string parameterName, SqliteType type, int si /// /// The parameter that was added. /// Parameters - public virtual SqliteParameter Add(string parameterName, SqliteType type, int size, string sourceColumn) + public virtual SqliteParameter Add(string? parameterName, SqliteType type, int size, string? sourceColumn) => Add(new SqliteParameter(parameterName, type, size, sourceColumn)); /// @@ -157,13 +157,8 @@ public virtual void AddRange(IEnumerable values) /// The parameter that was added. /// Parameters /// Data Types - public virtual SqliteParameter AddWithValue(string parameterName, object value) - { - var parameter = new SqliteParameter(parameterName, value); - Add(parameter); - - return parameter; - } + public virtual SqliteParameter AddWithValue(string? parameterName, object? value) + => Add(new SqliteParameter(parameterName, value)); /// /// Removes all parameters from the collection. diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteResultBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteResultBinder.cs index 7f14873f28d..4f066b903aa 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteResultBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteResultBinder.cs @@ -10,7 +10,7 @@ internal class SqliteResultBinder : SqliteValueBinder { private readonly sqlite3_context _ctx; - public SqliteResultBinder(sqlite3_context ctx, object value) + public SqliteResultBinder(sqlite3_context ctx, object? value) : base(value) { _ctx = ctx; diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteTransaction.cs b/src/Microsoft.Data.Sqlite.Core/SqliteTransaction.cs index 945b9c2edef..30e8a9a0acc 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteTransaction.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteTransaction.cs @@ -16,14 +16,14 @@ namespace Microsoft.Data.Sqlite /// Transactions public class SqliteTransaction : DbTransaction { - private SqliteConnection _connection; + private SqliteConnection? _connection; private readonly IsolationLevel _isolationLevel; private bool _completed; internal SqliteTransaction(SqliteConnection connection, IsolationLevel isolationLevel, bool deferred) { if ((isolationLevel == IsolationLevel.ReadUncommitted - && ((connection.ConnectionOptions.Cache != SqliteCacheMode.Shared) || !deferred)) + && ((connection.ConnectionOptions!.Cache != SqliteCacheMode.Shared) || !deferred)) || isolationLevel == IsolationLevel.ReadCommitted || isolationLevel == IsolationLevel.RepeatableRead) { @@ -57,14 +57,14 @@ internal SqliteTransaction(SqliteConnection connection, IsolationLevel isolation /// Gets the connection associated with the transaction. /// /// The connection associated with the transaction. - public new virtual SqliteConnection Connection + public new virtual SqliteConnection? Connection => _connection; /// /// Gets the connection associated with the transaction. /// /// The connection associated with the transaction. - protected override DbConnection DbConnection + protected override DbConnection? DbConnection => Connection; internal bool ExternalRollback { get; private set; } @@ -75,11 +75,11 @@ protected override DbConnection DbConnection /// /// The isolation level for the transaction. public override IsolationLevel IsolationLevel - => _completed || _connection.State != ConnectionState.Open + => _completed || _connection!.State != ConnectionState.Open ? throw new InvalidOperationException(Resources.TransactionCompleted) : _isolationLevel != IsolationLevel.Unspecified ? _isolationLevel - : (_connection.ConnectionOptions.Cache == SqliteCacheMode.Shared + : (_connection.ConnectionOptions!.Cache == SqliteCacheMode.Shared && _connection.ExecuteScalar("PRAGMA read_uncommitted;") != 0) ? IsolationLevel.ReadUncommitted : IsolationLevel.Serializable; @@ -91,7 +91,7 @@ public override void Commit() { if (ExternalRollback || _completed - || _connection.State != ConnectionState.Open) + || _connection!.State != ConnectionState.Open) { throw new InvalidOperationException(Resources.TransactionCompleted); } @@ -106,7 +106,7 @@ public override void Commit() /// public override void Rollback() { - if (_completed || _connection.State != ConnectionState.Open) + if (_completed || _connection!.State != ConnectionState.Open) { throw new InvalidOperationException(Resources.TransactionCompleted); } @@ -114,28 +114,22 @@ public override void Rollback() RollbackInternal(); } -#if NET /// public override bool SupportsSavepoints => true; -#endif /// /// Creates a savepoint in the transaction. This allows all commands that are executed after the savepoint was /// established to be rolled back, restoring the transaction state to what it was at the time of the savepoint. /// /// The name of the savepoint to be created. -#if NET public override void Save(string savepointName) -#else - public void Save(string savepointName) -#endif { if (savepointName is null) { throw new ArgumentNullException(nameof(savepointName)); } - if (_completed || _connection.State != ConnectionState.Open) + if (_completed || _connection!.State != ConnectionState.Open) { throw new InvalidOperationException(Resources.TransactionCompleted); } @@ -152,18 +146,14 @@ public void Save(string savepointName) /// Rolls back all commands that were executed after the specified savepoint was established. /// /// The name of the savepoint to roll back to. -#if NET public override void Rollback(string savepointName) -#else - public void Rollback(string savepointName) -#endif { if (savepointName is null) { throw new ArgumentNullException(nameof(savepointName)); } - if (_completed || _connection.State != ConnectionState.Open) + if (_completed || _connection!.State != ConnectionState.Open) { throw new InvalidOperationException(Resources.TransactionCompleted); } @@ -181,18 +171,14 @@ public void Rollback(string savepointName) /// reclaim some resources before the transaction ends. /// /// The name of the savepoint to release. -#if NET public override void Release(string savepointName) -#else - public void Release(string savepointName) -#endif { if (savepointName is null) { throw new ArgumentNullException(nameof(savepointName)); } - if (_completed || _connection.State != ConnectionState.Open) + if (_completed || _connection!.State != ConnectionState.Open) { throw new InvalidOperationException(Resources.TransactionCompleted); } @@ -216,7 +202,7 @@ protected override void Dispose(bool disposing) { if (disposing && !_completed - && _connection.State == ConnectionState.Open) + && _connection!.State == ConnectionState.Open) { RollbackInternal(); } @@ -224,7 +210,7 @@ protected override void Dispose(bool disposing) private void Complete() { - _connection.Transaction = null; + _connection!.Transaction = null; _connection = null; _completed = true; } @@ -233,7 +219,7 @@ private void RollbackInternal() { if (!ExternalRollback) { - sqlite3_rollback_hook(_connection.Handle, null, null); + sqlite3_rollback_hook(_connection!.Handle, null, null); _connection.ExecuteNonQuery("ROLLBACK;"); } @@ -242,7 +228,7 @@ private void RollbackInternal() private void RollbackExternal(object userData) { - sqlite3_rollback_hook(_connection.Handle, null, null); + sqlite3_rollback_hook(_connection!.Handle, null, null); ExternalRollback = true; } } diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index 9906f6b20b0..254d8ab030d 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -11,15 +11,15 @@ namespace Microsoft.Data.Sqlite // TODO: Make generic internal abstract class SqliteValueBinder { - private readonly object _value; + private readonly object? _value; private readonly SqliteType? _sqliteType; - protected SqliteValueBinder(object value) + protected SqliteValueBinder(object? value) : this(value, null) { } - protected SqliteValueBinder(object value, SqliteType? sqliteType) + protected SqliteValueBinder(object? value, SqliteType? sqliteType) { _value = value; _sqliteType = sqliteType; @@ -230,7 +230,7 @@ public virtual void Bind() { typeof(ushort), SqliteType.Integer } }; - internal static SqliteType GetSqliteType(object value) + internal static SqliteType GetSqliteType(object? value) { if (value == null) { diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs index 703d212146b..5a6e8d622a6 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueReader.cs @@ -87,7 +87,7 @@ public virtual Guid GetGuid(int ordinal) switch (sqliteType) { case SQLITE_BLOB: - var bytes = GetBlob(ordinal); + var bytes = GetBlob(ordinal)!; return bytes.Length == 16 ? new Guid(bytes) : new Guid(Encoding.UTF8.GetString(bytes, 0, bytes.Length)); @@ -130,7 +130,7 @@ public virtual string GetString(int ordinal) protected abstract string GetStringCore(int ordinal); - public virtual T GetFieldValue(int ordinal) + public virtual T? GetFieldValue(int ordinal) { if (IsDBNull(ordinal) && typeof(T).IsNullable()) @@ -151,7 +151,7 @@ public virtual T GetFieldValue(int ordinal) if (type == typeof(byte[])) { - return (T)(object)GetBlob(ordinal); + return (T)(object)GetBlob(ordinal)!; } if (type == typeof(char)) @@ -243,7 +243,7 @@ public virtual T GetFieldValue(int ordinal) return (T)GetValue(ordinal); } - public virtual object GetValue(int ordinal) + public virtual object? GetValue(int ordinal) { var sqliteType = GetSqliteType(ordinal); switch (sqliteType) @@ -266,7 +266,7 @@ public virtual object GetValue(int ordinal) } } - public virtual int GetValues(object[] values) + public virtual int GetValues(object?[] values) { int i; for (i = 0; i < FieldCount; i++) @@ -277,14 +277,14 @@ public virtual int GetValues(object[] values) return i; } - protected byte[] GetBlob(int ordinal) + protected virtual byte[]? GetBlob(int ordinal) => IsDBNull(ordinal) ? GetNull(ordinal) : GetBlobCore(ordinal) ?? Array.Empty(); protected abstract byte[] GetBlobCore(int ordinal); - protected virtual T GetNull(int ordinal) + protected virtual T? GetNull(int ordinal) => typeof(T) == typeof(DBNull) ? (T)(object)DBNull.Value : default; diff --git a/src/Microsoft.Data.Sqlite.Core/Utilities/ApplicationDataHelper.cs b/src/Microsoft.Data.Sqlite.Core/Utilities/ApplicationDataHelper.cs index 5dbef58ccac..9c6a9472595 100644 --- a/src/Microsoft.Data.Sqlite.Core/Utilities/ApplicationDataHelper.cs +++ b/src/Microsoft.Data.Sqlite.Core/Utilities/ApplicationDataHelper.cs @@ -8,25 +8,25 @@ namespace Microsoft.Data.Sqlite.Utilities { internal class ApplicationDataHelper { - private static object _appData; - private static string _localFolder; - private static string _tempFolder; + private static object? _appData; + private static string? _localFolder; + private static string? _tempFolder; - public static object CurrentApplicationData + public static object? CurrentApplicationData => _appData ??= LoadAppData(); - public static string TemporaryFolderPath + public static string? TemporaryFolderPath => _tempFolder ??= GetFolderPath("TemporaryFolder"); - public static string LocalFolderPath + public static string? LocalFolderPath => _localFolder ??= GetFolderPath("LocalFolder"); - private static object LoadAppData() + private static object? LoadAppData() { try { return Type.GetType("Windows.Storage.ApplicationData, Windows, ContentType=WindowsRuntime") - ?.GetRuntimeProperty("Current").GetValue(null); + ?.GetRuntimeProperty("Current")!.GetValue(null); } catch { @@ -35,12 +35,12 @@ private static object LoadAppData() } } - private static string GetFolderPath(string propertyName) + private static string? GetFolderPath(string propertyName) { var appDataType = CurrentApplicationData?.GetType(); - var temporaryFolder = appDataType?.GetRuntimeProperty(propertyName).GetValue(CurrentApplicationData); + var temporaryFolder = appDataType?.GetRuntimeProperty(propertyName)!.GetValue(CurrentApplicationData); - return temporaryFolder?.GetType().GetRuntimeProperty("Path").GetValue(temporaryFolder) as string; + return temporaryFolder?.GetType().GetRuntimeProperty("Path")!.GetValue(temporaryFolder) as string; } } } diff --git a/src/Microsoft.Data.Sqlite.Core/Utilities/BundleInitializer.cs b/src/Microsoft.Data.Sqlite.Core/Utilities/BundleInitializer.cs index bad6155570d..fc81cd52927 100644 --- a/src/Microsoft.Data.Sqlite.Core/Utilities/BundleInitializer.cs +++ b/src/Microsoft.Data.Sqlite.Core/Utilities/BundleInitializer.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Reflection; using static SQLitePCL.raw; @@ -13,7 +14,7 @@ internal static class BundleInitializer public static void Initialize() { - Assembly assembly = null; + Assembly? assembly = null; try { assembly = Assembly.Load(new AssemblyName("SQLitePCLRaw.batteries_v2")); @@ -24,7 +25,7 @@ public static void Initialize() if (assembly != null) { - assembly.GetType("SQLitePCL.Batteries_V2").GetTypeInfo().GetDeclaredMethod("Init") + assembly.GetType("SQLitePCL.Batteries_V2", throwOnError: true)!.GetMethod("Init", Type.EmptyTypes)! .Invoke(null, null); } diff --git a/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj b/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj index 9ce620f8e70..eda1254a068 100644 --- a/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj +++ b/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj @@ -15,7 +15,7 @@ Microsoft.Data.Sqlite.SqliteFactory Microsoft.Data.Sqlite.SqliteParameter Microsoft.Data.Sqlite.SqliteTransaction false - netstandard2.0 + net5.0 3.6 SQLite;Data;ADO.NET false diff --git a/src/Microsoft.Data.Sqlite/lib/netstandard2.0/_._ b/src/Microsoft.Data.Sqlite/lib/net5.0/_._ similarity index 100% rename from src/Microsoft.Data.Sqlite/lib/netstandard2.0/_._ rename to src/Microsoft.Data.Sqlite/lib/net5.0/_._ diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj index 45a5310a61a..524711b65df 100644 --- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj +++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj @@ -3,6 +3,7 @@ net5.0 $(DefineConstants);E_SQLITE3 + enable diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj index 93e6f74661f..ab21812f69e 100644 --- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj +++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj @@ -3,6 +3,7 @@ net5.0 $(DefineConstants);E_SQLCIPHER + enable diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj index 23876c27817..1782777ba10 100644 --- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj +++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj @@ -3,6 +3,7 @@ net5.0 $(DefineConstants);SQLITE3 + enable diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj index 6e7753dc77e..7bfaa028202 100644 --- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj +++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj @@ -3,6 +3,7 @@ net5.0 $(DefineConstants);WINSQLITE3 + enable diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteBlobTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteBlobTest.cs index 2cbe720a867..907c3a9e489 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteBlobTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteBlobTest.cs @@ -47,7 +47,7 @@ public void Ctor_throws_when_error() public void Ctor_throws_when_table_null() { var ex = Assert.Throws( - () => new SqliteBlob(_connection, null, Column, Rowid)); + () => new SqliteBlob(_connection, null!, Column, Rowid)); Assert.Equal("tableName", ex.ParamName); } @@ -55,7 +55,7 @@ public void Ctor_throws_when_table_null() public void Ctor_throws_when_column_null() { var ex = Assert.Throws( - () => new SqliteBlob(_connection, Table, null, Rowid)); + () => new SqliteBlob(_connection, Table, null!, Rowid)); Assert.Equal("columnName", ex.ParamName); } @@ -154,7 +154,7 @@ public void Read_throws_when_buffer_null() using (var stream = CreateStream()) { var ex = Assert.Throws( - () => stream.Read(null, 0, 1)); + () => stream.Read(null!, 0, 1)); Assert.Equal("buffer", ex.ParamName); } @@ -335,7 +335,7 @@ public void Write_throws_when_buffer_null() using (var stream = CreateStream()) { var ex = Assert.Throws( - () => stream.Write(null, 0, 0)); + () => stream.Write(null!, 0, 0)); Assert.Equal("buffer", ex.ParamName); } } @@ -421,6 +421,22 @@ public void Write_throws_when_disposed() () => stream.Write(new byte[] { 3 }, 0, 1)); } + [Fact] + public void Empty_works() + { + using var connection = new SqliteConnection("Data Source=:memory:"); + connection.Open(); + + connection.ExecuteNonQuery( + @" + CREATE TABLE """" ("""" BLOB); + INSERT INTO """" (rowid, """") VALUES(1, X'02'); + "); + + using var stream = new SqliteBlob(connection, "", "", 1); + Assert.Equal(2, stream.ReadByte()); + } + protected Stream CreateStream(bool readOnly = false) => new SqliteBlob(_connection, Table, Column, Rowid, readOnly); diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteCommandTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteCommandTest.cs index 0f5cbe3756d..a403fdd4489 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteCommandTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteCommandTest.cs @@ -165,15 +165,13 @@ public void Prepare_throws_when_connection_closed() } [Fact] - public void Prepare_throws_when_no_command_text() + public void Prepare_works_when_no_command_text() { using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - var ex = Assert.Throws(() => connection.CreateCommand().Prepare()); - - Assert.Equal(Resources.CallRequiresSetCommandText("Prepare"), ex.Message); + connection.CreateCommand().Prepare(); } } @@ -255,15 +253,16 @@ public void ExecuteReader_throws_when_connection_closed() } [Fact] - public void ExecuteReader_throws_when_no_command_text() + public void ExecuteReader_works_when_no_command_text() { using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - var ex = Assert.Throws(() => connection.CreateCommand().ExecuteReader()); + using var reader = connection.CreateCommand().ExecuteReader(); - Assert.Equal(Resources.CallRequiresSetCommandText("ExecuteReader"), ex.Message); + Assert.False(reader.HasRows); + Assert.Equal(-1, reader.RecordsAffected); } } @@ -326,9 +325,9 @@ public void ExecuteScalar_throws_when_no_command_text() { connection.Open(); - var ex = Assert.Throws(() => connection.CreateCommand().ExecuteScalar()); + var result = connection.CreateCommand().ExecuteScalar(); - Assert.Equal(Resources.CallRequiresSetCommandText("ExecuteScalar"), ex.Message); + Assert.Null(result); } } @@ -541,15 +540,15 @@ public void ExecuteNonQuery_throws_when_connection_closed() } [Fact] - public void ExecuteNonQuery_throws_when_no_command_text() + public void ExecuteNonQuery_works_when_no_command_text() { using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - var ex = Assert.Throws(() => connection.CreateCommand().ExecuteNonQuery()); + var result = connection.CreateCommand().ExecuteNonQuery(); - Assert.Equal(Resources.CallRequiresSetCommandText("ExecuteNonQuery"), ex.Message); + Assert.Equal(-1, result); } } diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionTest.cs index 582a59f2221..531c7a35585 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionTest.cs @@ -134,13 +134,11 @@ public void State_closed_by_default() } [Fact] - public void Open_throws_when_no_connection_string() + public void Open_works_when_no_connection_string() { - var connection = new SqliteConnection(); - - var ex = Assert.Throws(() => connection.Open()); + using var connection = new SqliteConnection(); - Assert.Equal(Resources.OpenRequiresSetConnectionString, ex.Message); + connection.Open(); } [Fact] @@ -436,7 +434,7 @@ public void BackupDatabase_throws_when_destination_null() { connection.Open(); - var ex = Assert.Throws(() => connection.BackupDatabase(null)); + var ex = Assert.Throws(() => connection.BackupDatabase(null!)); Assert.Equal("destination", ex.ParamName); } @@ -611,7 +609,7 @@ public void CreateCollation_throws_with_empty_name() using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - var ex = Assert.Throws(() => connection.CreateCollation(null, null)); + var ex = Assert.Throws(() => connection.CreateCollation(null!, null)); Assert.Equal("name", ex.ParamName); } @@ -659,7 +657,7 @@ public void CreateFunction_throws_when_no_name() using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - var ex = Assert.Throws(() => connection.CreateFunction(null, () => 1L)); + var ex = Assert.Throws(() => connection.CreateFunction(null!, () => 1L)); Assert.Equal("name", ex.ParamName); } @@ -744,7 +742,7 @@ public void CreateFunction_works_when_result_null() using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - connection.CreateFunction("test", () => null); + connection.CreateFunction("test", () => null); var result = connection.ExecuteScalar("SELECT test();"); @@ -819,7 +817,7 @@ public void CreateFunction_works_when_parameter_null_and_type_string() using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - connection.CreateFunction("test", (string x) => x == null); + connection.CreateFunction("test", (string? x) => x == null); var result = connection.ExecuteScalar("SELECT test(NULL);"); @@ -913,7 +911,7 @@ public void CreateAggregate_throws_when_no_name() using (var connection = new SqliteConnection("Data Source=:memory:")) { connection.Open(); - var ex = Assert.Throws(() => connection.CreateAggregate(null, (string a) => "A")); + var ex = Assert.Throws(() => connection.CreateAggregate(null!, (string? a) => "A")); Assert.Equal("name", ex.ParamName); } @@ -945,7 +943,7 @@ public void CreateAggregate_works_when_params() { connection.Open(); connection.ExecuteNonQuery("CREATE TABLE dual (dummy); INSERT INTO dual (dummy) VALUES ('X');"); - connection.CreateAggregate("test", (string a, object[] args) => a + string.Join(", ", args) + "; "); + connection.CreateAggregate("test", (string? a, object?[] args) => a + string.Join(", ", args) + "; "); var result = connection.ExecuteScalar("SELECT test(dummy) FROM dual;"); @@ -960,7 +958,7 @@ public void CreateAggregate_works_when_exception_during_step() { connection.Open(); connection.ExecuteNonQuery("CREATE TABLE dual (dummy); INSERT INTO dual (dummy) VALUES ('X');"); - connection.CreateAggregate("test", (string a) => throw new Exception("Test")); + connection.CreateAggregate("test", (string? a) => throw new Exception("Test")); var ex = Assert.Throws( () => connection.ExecuteScalar("SELECT test() FROM dual;")); @@ -992,7 +990,7 @@ public void CreateAggregate_works_when_sqlite_exception() { connection.Open(); connection.ExecuteNonQuery("CREATE TABLE dual (dummy); INSERT INTO dual (dummy) VALUES ('X');"); - connection.CreateAggregate("test", (string a) => throw new SqliteException("Test", 200)); + connection.CreateAggregate("test", (string? a) => throw new SqliteException("Test", 200)); var ex = Assert.Throws( () => connection.ExecuteScalar("SELECT test() FROM dual;")); @@ -1008,8 +1006,8 @@ public void CreateAggregate_works_when_null() { connection.Open(); connection.ExecuteNonQuery("CREATE TABLE dual (dummy); INSERT INTO dual (dummy) VALUES ('X');"); - connection.CreateAggregate("test", (string a) => "A"); - connection.CreateAggregate("test", default(Func)); + connection.CreateAggregate("test", (string? a) => "A"); + connection.CreateAggregate("test", default(Func)); var ex = Assert.Throws( () => connection.ExecuteScalar("SELECT test() FROM dual;")); diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs index a6289e30f40..31420413799 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs @@ -160,12 +160,9 @@ public void GetBytes_NullBuffer() var hasData = reader.Read(); Assert.True(hasData); - byte[] buffer = null; - long bytesRead = reader.GetBytes(0, 1, buffer, 0, 3); + long bytesRead = reader.GetBytes(0, 1, null, 0, 3); - // Expecting to return the length of the field in bytes, - // which can be simply be blob length minus the offset. - Assert.Equal(3, bytesRead); + Assert.Equal(4, bytesRead); } } } @@ -236,14 +233,33 @@ public void GetChars_works() { connection.Open(); - using (var reader = connection.ExecuteReader("SELECT 'test';")) + using (var reader = connection.ExecuteReader("SELECT 'têst';")) { var hasData = reader.Read(); Assert.True(hasData); var buffer = new char[2]; reader.GetChars(0, 1, buffer, 0, buffer.Length); - Assert.Equal(new char[2] { 'e', 's' }, buffer); + Assert.Equal(new char[2] { 'ê', 's' }, buffer); + } + } + } + + [Fact] + public void GetChars_works_when_buffer_null() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + connection.Open(); + + using (var reader = connection.ExecuteReader("SELECT 'têst';")) + { + var hasData = reader.Read(); + Assert.True(hasData); + + long bytesRead = reader.GetChars(0, 1, null, 0, 3); + + Assert.Equal(4, bytesRead); } } } @@ -255,7 +271,7 @@ public void GetChars_works_with_overflow() { connection.Open(); - using (var reader = connection.ExecuteReader("SELECT 'test';")) + using (var reader = connection.ExecuteReader("SELECT 'têst';")) { var hasData = reader.Read(); Assert.True(hasData); @@ -264,7 +280,7 @@ public void GetChars_works_with_overflow() long charsRead = reader.GetChars(0, 1, hugeBuffer, 0, hugeBuffer.Length); Assert.Equal(3, charsRead); - var correctBytes = new char[3] { 'e', 's', 't' }; + var correctBytes = new char[3] { 'ê', 's', 't' }; for (int i = 0; i < charsRead; i++) { Assert.Equal(correctBytes[i], hugeBuffer[i]); @@ -280,7 +296,7 @@ public void GetChars_throws_when_dataOffset_out_of_range() { connection.Open(); - using (var reader = connection.ExecuteReader("SELECT 'test';")) + using (var reader = connection.ExecuteReader("SELECT 'têst';")) { var hasData = reader.Read(); Assert.True(hasData); @@ -296,12 +312,12 @@ public void GetChars_throws_when_dataOffset_out_of_range() [Fact] public void GetChars_throws_when_closed() { - X_throws_when_closed(r => r.GetChars(0, 0, null, 0, 0), nameof(SqliteDataReader.GetChars)); + X_throws_when_closed(r => r.GetChars(0, 0, null!, 0, 0), nameof(SqliteDataReader.GetChars)); } [Fact] public void GetChars_throws_when_non_query() - => X_throws_when_non_query(r => r.GetChars(0, 0, null, 0, 0)); + => X_throws_when_non_query(r => r.GetChars(0, 0, null!, 0, 0)); [Fact] public void GetChars_works_streaming() @@ -310,7 +326,7 @@ public void GetChars_works_streaming() { connection.Open(); - connection.ExecuteNonQuery("CREATE TABLE Data (Value); INSERT INTO Data VALUES ('test');"); + connection.ExecuteNonQuery("CREATE TABLE Data (Value); INSERT INTO Data VALUES ('têst');"); using (var reader = connection.ExecuteReader("SELECT rowid, Value FROM Data;")) { @@ -319,7 +335,7 @@ public void GetChars_works_streaming() var buffer = new char[2]; reader.GetChars(1, 1, buffer, 0, buffer.Length); - Assert.Equal(new[] { 'e', 's' }, buffer); + Assert.Equal(new[] { 'ê', 's' }, buffer); } } } @@ -1179,7 +1195,7 @@ public void GetOrdinal_throws_when_out_of_range() [Fact] public void GetOrdinal_throws_when_closed() { - X_throws_when_closed(r => r.GetOrdinal(null), nameof(SqliteDataReader.GetOrdinal)); + X_throws_when_closed(r => r.GetOrdinal(null!), nameof(SqliteDataReader.GetOrdinal)); } [Fact] @@ -1320,12 +1336,12 @@ public void GetValues_throws_when_too_narrow() [Fact] public void GetValues_throws_when_closed() { - X_throws_when_closed(r => r.GetValues(null), nameof(SqliteDataReader.GetValues)); + X_throws_when_closed(r => r.GetValues(null!), nameof(SqliteDataReader.GetValues)); } [Fact] public void GetValues_throws_when_non_query() - => X_throws_when_non_query(r => r.GetValues(null)); + => X_throws_when_non_query(r => r.GetValues(null!)); [Fact] public void HasRows_returns_true_when_rows() diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs index 7faa2b540fb..6bfc38c0c39 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs @@ -467,7 +467,7 @@ public void Bind_DateTime_with_Arabic_Culture() Assert.Equal(1, command.ExecuteNonQuery()); command.CommandText = "SELECT DateOfBirth FROM Person;"; - var result = command.ExecuteScalar(); + var result = command.ExecuteScalar()!; Assert.Equal("2018-03-25 00:00:00", (string)result); using (var reader = command.ExecuteReader()) @@ -495,7 +495,7 @@ public void Bind_DateTimeOffset_with_Arabic_Culture() Assert.Equal(1, command.ExecuteNonQuery()); command.CommandText = "SELECT date FROM Test;"; - var result = command.ExecuteScalar(); + var result = command.ExecuteScalar()!; Assert.Equal("2018-03-25 00:00:00+00:00", (string)result); using (var reader = command.ExecuteReader()) diff --git a/test/Microsoft.Data.Sqlite.Tests/TestUtilities/UseCultureAttribute.cs b/test/Microsoft.Data.Sqlite.Tests/TestUtilities/UseCultureAttribute.cs index 4c9f7fc87bd..04361bba4df 100644 --- a/test/Microsoft.Data.Sqlite.Tests/TestUtilities/UseCultureAttribute.cs +++ b/test/Microsoft.Data.Sqlite.Tests/TestUtilities/UseCultureAttribute.cs @@ -11,8 +11,8 @@ namespace Microsoft.Data.Sqlite.TestUtilities [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public sealed class UseCultureAttribute : BeforeAfterTestAttribute { - private CultureInfo _originalCulture; - private CultureInfo _originalUICulture; + private CultureInfo? _originalCulture; + private CultureInfo? _originalUICulture; public UseCultureAttribute(string culture) : this(culture, culture) @@ -39,8 +39,8 @@ public override void Before(MethodInfo methodUnderTest) public override void After(MethodInfo methodUnderTest) { - CultureInfo.CurrentCulture = _originalCulture; - CultureInfo.CurrentUICulture = _originalUICulture; + CultureInfo.CurrentCulture = _originalCulture!; + CultureInfo.CurrentUICulture = _originalUICulture!; } } } diff --git a/tools/SqliteResources.tt b/tools/SqliteResources.tt index a5a8f6d615d..97e04ca8b08 100644 --- a/tools/SqliteResources.tt +++ b/tools/SqliteResources.tt @@ -17,6 +17,8 @@ using System.Reflection; using System.Resources; +#nullable enable + namespace <#= model.Namespace #> { internal static class <#= model.Class #> @@ -60,7 +62,7 @@ namespace <#= model.Namespace #> private static string GetString(string name, params string[] formatterNames) { - var value = _resourceManager.GetString(name); + var value = _resourceManager.GetString(name)!; for (var i = 0; i < formatterNames.Length; i++) { value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");